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

推荐订阅源

Forbes - Security
Forbes - Security
L
Lohrmann on Cybersecurity
Simon Willison's Weblog
Simon Willison's Weblog
P
Proofpoint News Feed
P
Privacy International News Feed
The Hacker News
The Hacker News
AWS News Blog
AWS News Blog
S
Securelist
P
Proofpoint News Feed
Recent Announcements
Recent Announcements
GbyAI
GbyAI
B
Blog RSS Feed
A
About on SuperTechFans
C
CXSECURITY Database RSS Feed - CXSecurity.com
Y
Y Combinator Blog
Microsoft Azure Blog
Microsoft Azure Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyberwarzone
Cyberwarzone
I
Intezer
T
Tor Project blog
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
aimingoo的专栏
aimingoo的专栏
Cisco Talos Blog
Cisco Talos Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
W
WeLiveSecurity
D
DataBreaches.Net
U
Unit 42
Project Zero
Project Zero
Martin Fowler
Martin Fowler
V
V2EX
The Last Watchdog
The Last Watchdog
Security Archives - TechRepublic
Security Archives - TechRepublic
C
Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V2EX - 技术
V2EX - 技术
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Threat Research - Cisco Blogs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Tenable Blog
F
Full Disclosure
T
The Exploit Database - CXSecurity.com
H
Heimdal Security Blog
Latest news
Latest news
Webroot Blog
Webroot 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;
}