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

推荐订阅源

A
About on SuperTechFans
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tenable Blog
WordPress大学
WordPress大学
小众软件
小众软件
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
大猫的无限游戏
大猫的无限游戏
T
The Exploit Database - CXSecurity.com
Attack and Defense Labs
Attack and Defense Labs
Simon Willison's Weblog
Simon Willison's Weblog
C
CXSECURITY Database RSS Feed - CXSecurity.com
量子位
有赞技术团队
有赞技术团队
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
S
Schneier on Security
Engineering at Meta
Engineering at Meta
Microsoft Azure Blog
Microsoft Azure Blog
Martin Fowler
Martin Fowler
Recent Announcements
Recent Announcements
Stack Overflow Blog
Stack Overflow Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
阮一峰的网络日志
阮一峰的网络日志
G
GRAHAM CLULEY
Spread Privacy
Spread Privacy
F
Full Disclosure
Scott Helme
Scott Helme
GbyAI
GbyAI
N
Netflix TechBlog - Medium
MyScale Blog
MyScale Blog
Cloudbric
Cloudbric
云风的 BLOG
云风的 BLOG
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
Hacker News - Newest:
Hacker News - Newest: "LLM"
Security Latest
Security Latest
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
The GitHub Blog
The GitHub Blog
The Register - Security
The Register - Security
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Secure Thoughts
C
Check Point 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;
}