惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CXSECURITY Database RSS Feed - CXSecurity.com
D
Docker
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
Jina AI
Jina AI
小众软件
小众软件
Last Week in AI
Last Week in AI
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
美团技术团队
爱范儿
爱范儿
V
V2EX
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
博客园 - 司徒正美
博客园 - 叶小钗
S
SegmentFault 最新的问题
量子位
S
Secure Thoughts
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
O
OpenAI News
L
LINUX DO - 最新话题
罗磊的独立博客
SecWiki News
SecWiki News
雷峰网
雷峰网
Recent Announcements
Recent Announcements
V2EX - 技术
V2EX - 技术
T
Tailwind CSS Blog
H
Hacker News: Front Page
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
云风的 BLOG
云风的 BLOG
Schneier on Security
Schneier on Security
T
The Blog of Author Tim Ferriss
IT之家
IT之家
博客园 - 聂微东
腾讯CDC
N
News | PayPal Newsroom
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
Hacker News: Ask HN
Hacker News: Ask HN
aimingoo的专栏
aimingoo的专栏
Webroot Blog
Webroot Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
K
Kaspersky official blog

PYM博客

Python 部署 Lexfence:基于 AI 大模型的内容审核系统 Docker 部署 Lexfence:一款开源易用的AI审核服务 2026年了,电脑病毒真是防不胜防,3个好用的杀毒软件推荐(亲身经历) 本站已更换 Cloudflare 至 EdgeOne Claude Opus 4.8来了!不再是比聪明,而是更能干活,敢于认错,变得诚实了! Note.ms在线简洁匿名记事本,如何修改/0页面 解禁了?RTX 5090 PRO6000上架京东自营店 用工具轻松的给Frpc配置SSL证书,穿透Http与Https流量,开启强制Https跳转 「POJ1740」A New Stone Game SG函数与博弈论题解 Deepseek V4发布了!综合能力比肩顶级闭源模型! 国内就可以使用的免费SuperGrok,无需登录无需排队,完全公益免费! 保姆级干货:在AI时代薅羊毛,如何获得大量免费的AI API?学完这个你的小龙虾就不缺粮食了! Deepseek-V4要来了的预兆?Deepseek专家模式低调上新!Deepseek首次引入模式分层! 游玩本站必读公告 Claude Code源代码惨遭泄露,几句话告诉你泄露的原因,附下载链接 Docker快速部署Astrbot,开源的一站式 Agentic 个人和群聊助手 今天是愚人节,请将这篇文章转发给你的亲朋好友 P4171 [JSOI2010] 满汉全席 2-SAT详细题解 P6145 [USACO20FEB] Timeline G SPFA差分约束最长路题解 Luogu P2850 [USACO06DEC] Wormholes G SPFA算法思路与C++代码详解 Luogu P2136 拉近距离 SPFA判断负环题解 与 思路 开源 UI 元素社区库,让你的网站更加美观! 免费的AI和付费的API区别到底在哪里?付费的AI真的更聪明吗?
P1993 小 K 的农场 差分约束SPFA判断负环 详细题解
PYM · 2026-03-27 · via PYM博客

题目传送门

题目大意

一共 NN 个点, MM 条边。

33 种类型的边:

  1. 单向边:从点 ii 到点 jj 至少有 cc,也就是 aiajc

  2. 单向边:从点 ii 到点 jj 至多有 ccaiajc

  3. 双向边:从点 ii 到点 jj一样多,ai=aj


将这 33 种边转换一下可以得到:

  1. ajaic

  2. aiaj+c

  3. ai=aj+0aj=ai+0

解题思路

判断负环

如果K的记忆冲突了,那么就说明有负环(小K绕晕了😵),输出 NO

如果K的记忆有至少1种情况没有冲突, 那么就说明图中不存在负环,则输出 YES

// 判断负环
cnt[v] = cnt[u] + 1;
if (cnt[v] > n) {
	cout << "No\n"; // 有,就输出NO
	exit(0);
}


// 没有负环,在函数外输出YES
spfa(0);
cout << "Yes\n";
return 0;

处理 3 种边

cc 代表从某一点至某一点的边所需的花费。

对于第一种,从点 ii 到点 jj 至少cc

观察式子 ajaic 可得出 从点 ii到点 jj 花费为 −c-c

对于第二种,从点 ii 到点 jj 至多cc

观察式子 aiaj+c 可得出 从点 jj到点 ii 花费为 cc

对于第三种,从点 iijj 数量一样,即 cc00

观察式子 ai=aj+0aj=ai+0 可得出 从点 i/ji/j到点 i/ji/j 花费为 00,是一条双向边

for (int i = 1; i <= m; ++i) {
	int op; cin >> op;
	int u, v, w = 0;
	if (op == 1) {
		cin >> u >> v >> w;
		e[u].emplace_back(v, -w);
	} else if (op == 2) {
		cin >> u >> v >> w;
		e[v].emplace_back(u, w);
	} else {
		cin >> u >> v;
		e[u].emplace_back(v, 0);
		e[v].emplace_back(u, 0);
	}
}

超级源点

因为题目并没有规定从哪一点出发,且题目需要求解出所有情况来判断

因此我们需要一个超级源点来连接所有点,方便求出所有情况

for (int i = 1; i <= n; ++i) e[0].emplace_back(i, 0);

AC代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e4 + 5;
int n, m;
vector<vector<pair<int, int>>> e(N);
ll dis[N]; // 记录距离
int cnt[N]; // 记录任意点在队列的次数,以便判断负环
bool vis[N]; // 记录任意点是否在队列中
void spfa(int s) { // SPFA板子
	queue<int> q;
	q.emplace(s);
	fill(dis + 1, dis + n + 1, INT_MAX); //SPFA必要的初始化
	vis[s] = true;
	dis[s] = 0; // 从超级源点0出发
	while (!q.empty()) {
		int u = q.front(); q.pop();
		vis[u] = false;
		for (auto tmp : e[u]) { // 适配C++14的写法
			int v, w;
			tie(v, w) = tmp;
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				cnt[v] = cnt[u] + 1; // 累计点v在队列的次数,因为每个点至多n次,所有如果>n就是有负环
				if (cnt[v] > n) {
					cout << "No\n"; // 有负环,输出NO
					exit(0); // exit(0)是退出整个程序
				}
				if (!vis[v]) {
					vis[v] = true;
					q.emplace(v);
				}
			}
		}
	}
}
int main() {
	// 输入输出加速
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		int op; cin >> op;
		int u, v, w = 0;
		if (op == 1) { // 第一种边:农场a比农场b至少多种植了c个单位的作物
			cin >> u >> v >> w;
			e[u].emplace_back(v, -w);
		} else if (op == 2) { // 第二种边:农场a比农场b至多多种植了c个单位的作物
			cin >> u >> v >> w;
			e[v].emplace_back(u, w);
		} else { // 第三种边:农场a终止的数量和b一样多
			cin >> u >> v;
			e[u].emplace_back(v, 0);
			e[v].emplace_back(u, 0);
		}
	}
	for (int i = 1; i <= n; ++i) e[0].emplace_back(i, 0); // 建立超级源点
	spfa(0);
	cout << "Yes\n"; // 没有负环输出YES
	return 0;
}