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

推荐订阅源

博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
月光博客
月光博客
AI
AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
CXSECURITY Database RSS Feed - CXSecurity.com
WordPress大学
WordPress大学
GbyAI
GbyAI
L
Lohrmann on Cybersecurity
O
OpenAI News
Schneier on Security
Schneier on Security
P
Palo Alto Networks Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
W
WeLiveSecurity
L
LINUX DO - 最新话题
人人都是产品经理
人人都是产品经理
S
Security Affairs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
Arctic Wolf
Recorded Future
Recorded Future
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
GRAHAM CLULEY
N
Netflix TechBlog - Medium
TaoSecurity Blog
TaoSecurity Blog
C
Check Point Blog
Scott Helme
Scott Helme
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Vercel News
Vercel News
The Hacker News
The Hacker News
Y
Y Combinator Blog
Latest news
Latest news
SecWiki News
SecWiki News
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cisco Blogs
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
宝玉的分享
宝玉的分享
L
LINUX DO - 热门话题

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详细题解 P1993 小 K 的农场 差分约束SPFA判断负环 详细题解 P6145 [USACO20FEB] Timeline G SPFA差分约束最长路题解 Luogu P2136 拉近距离 SPFA判断负环题解 与 思路 开源 UI 元素社区库,让你的网站更加美观! 免费的AI和付费的API区别到底在哪里?付费的AI真的更聪明吗?
Luogu P2850 [USACO06DEC] Wormholes G SPFA算法思路与C++代码详解
PYM · 2026-03-21 · via PYM博客

先放图

批注 2026-03-21 144145.png

题目

洛谷传送门

题目背景

英文题面见此链接

题目描述

Farmer John 在探索他的农场时发现了许多神奇的虫洞。虫洞的特性非常特殊——它是一个单向通道,能将你传送到它的目的地,而且时间还会回溯到过去!FJ 的每个农场包含 N(1≤N≤500) 块编号为 1∼N 的田地、M(1≤M≤2500) 条双向路径和 W(1≤W≤200) 个虫洞。

作为狂热的时间旅行爱好者,FJ 希望实现:从某块田地出发,经过若干路径和虫洞后,在初始离开时间之前回到起点。这样或许他能遇见自己 :)

为了判断可行性,FJ 将提供 F(1≤F≤5) 个农场的完整地图。所有路径通行耗时不超过 10,000 秒,虫洞最多能将 FJ 带回 10,000 秒前。

输入格式

1 行:一个整数 F,表示农场数。后续为 F 个农场的数据。

每个农场:

  • 1 行:三个空格分隔的整数 N(田地数), M(双向路径数), W(虫洞数)。

  • 2∼M+1 行:每行三个空格分隔的整数 (S,E,T),表示 SE 间有一条耗时 T 秒的双向路径。两块田地间可能存在多条路径。

  • M+2∼M+W+1 行:每行三个空格分隔的整数 (S,E,T),表示一条从 SE 的单向虫洞,可将 FJ 带回 T 秒前。

输出格式

输出 F 行:对每个农场,若 FJ 能达成目标输出YES,否则输出NO

输入输出样例

输入 #1

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

输出 #1

NO
YES

说明/提示

  • 农场 1:FJ 无法实现时间回溯。

  • 农场 2:FJ 可通过环 1→2→3→1 回到起点 1 秒前(可从环上任意点出发实现)。

翻译:DeepSeek-R1

思路

题目解析

这是一道SPFA板子题,题目大意可以理解为:

  • NN个点

  • MM条双向边,经过会增加时间

  • WW条单向边,经过可以减少时间(穿越了

然后这是一道多组测试数据的题,有 FF组数据

题目需要你求出,从任意一点出发,会不会遇到负环(因为有负环,所以FJ可以回到起点),有就输出 YES ,没有也就是FJ没法回到起点,输出 NO

代码构思

首先注意到我们可以从任意点出发,所以我们需要建一个 超级源点, 有了超级源点后,我们跑SPFA从超级源点出发,这样就可以到达所有点,避免了跑很多遍SPFA来求最优解。那么超级源点是什么呢?就是一个点,比如点0,连接了其他所有点,然后每条连接的边都是单向边,且花费为0,这里我们搭配图片理解:

然后就是SPFA求负环的板子了,不知道SPFA怎么求负环的可以看看这篇文章,里面有讲SPFA如何求负环,那么最终代码如下:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 500 + 5;
int T;
int n, m, mm;
vector<vector<pair<int, int>>> e; // 奇葩STL,不喜欢可以写结构体,会麻烦点
ll dis[N]; // 没啥用的距离数组,辅助求负环
bool vis[N]; // 标记任意点是否在队列中
int cnt[N]; // 标记任意点的使用次数,用来求负环
bool spfa() {
	// 初始化
	fill(dis + 1, dis + n + 1, INT_MAX);
	fill(cnt + 1, cnt + n + 1, 0);
	fill(vis + 1, vis + n + 1, false);
	queue<int> q;
	q.emplace(0);
	dis[0] = 0;
	vis[0] = true;

	// SPFA板子
	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; // 求负环
				if (cnt[v] > n) return false; // 多了一个超级源点,所以是大于n,有负环
				if (!vis[v]) {
					vis[v] = true;
					q.emplace(v);
				}
			}
		}
	}
	return true; //没有负环
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> T;
	while (T--) {
		// 因为有多组数据,每次e数组清空,然后重设大小
		e.clear();
		e.resize(N);
		cin >> n >> m >> mm;
		for (int i = 1; i <= m; ++i) {
			int u, v, w;
			cin >> u >> v >> w; // 输入普通的双向边
			e[u].emplace_back(v, w);
			e[v].emplace_back(u, w);
		}
		for (int i = 1; i <= mm; ++i) {
			int u, v, w;
			cin >> u >> v >> w; // 输入虫洞
			e[u].emplace_back(v, -w);
		}
		
		// 超级源点
		for (int i = 1; i <= n; ++i) {
			e[0].emplace_back(i, 0); // 建立单向边,将0指向其他所有点,且花费为0
		}
		cout << (spfa() ? "NO" : "YES") << "\n"; // 有负环就是可以回到起点,输出YES,否则是NO
	}
	return 0;
}