POJ3259 判断是否存在负权环
来源:互联网 发布:德拉蒙德格林2016数据 编辑:程序博客网 时间:2024/06/05 05:05
Description
While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ’s farms comprises
As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .
To help FJ find out whether this is possible or not, he will supply you with complete maps to
Input
Line 1: A single integer,
Line 1 of each farm: Three space-separated integers respectively:
Lines
Lines
Output
Lines
Sample Input
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
Sample Output
NO
YES
Hint
For farm 1, FJ cannot travel back in time.
For farm 2, FJ could travel back in time by the cycle
如果你想要翻译的话 :
题目描述
John 的农场里 N(N < = 500)块地,M(M <= 2500)条双向路分别连接两块地,有 W(W <= 200)个时空隧道,时空隧道是一条单向路,当你走完一条时空隧道的时候时间会倒退 T 秒。我们的任务是想知道 John 能不能从某块地出发后又回来,使得他回来的时间早于出发的时间,就是说可能在自己从起点出发之前就回来了(时空逆转)。
输入格式
第一行:一个正整数 x,表示有
第 1 行:三个正整数,即
接下来有 M 行,每行三个正整数
接下来有
输出格式
对于每组测试数据,输出一个单词,如果 John 能够成功,输出“YES”,否则输出“NO”。
备注
[样例说明]
第一组样例:John不能早于出发时间回到出发位置.
第二组样例:John能够在他离开前1秒,通过循环回到出发位置:
BFS-SPFA
网上写的大多的 BFS-SPFA 其实跟我们平时写的 SPFA 是相似的, 所谓加上 BFS 用来区分 DFS-SPFA,其实 SPFA 常见的实现方式就是 BFS 的想法,所以我这里不多叙述。BFS-SPFA 判负环的思想 : 一个的点入栈大 n 次,那么图一定存在负环。但是这种方法并不推荐,因为你的一个的点入栈大于 n 次,那么其环上的点一定也有
我这里就给个伪代码。手打并没有编译。
inline void BFS_DFS(int s) { for(int i = 1; i <= n; ++i) dis[i] = num[i] = instack[i] = 0; dis[s] = 0; instack[s] = true; ++num[s]; queue<int> q; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); instack[u] = false; for(int i = first[u]; i; i = nxt[i]) if(dis[to[i] > dis[u] + len[i]) { dis[to[i]] = dis[u] + len[i]; if(!instack[to[i]]) { ++num[to[i]]; q.push(to[i]); if(num[to[i]] > n) { flag = 1; return; } } } }}inline void judge() { if(flag) printf("YES\n"); else printf("NO\n");}
DFS-SPFA
DFS-SPFA 在网上大多数都是判断一个点是否在一条路径上存在多次,当然在写法就是判断当前如要被更新并且还在栈中就可以判断图中存在负环,其写法和 dij 有点相同,但是这样的话我扫了很多没有用的边,于是我们考虑优化。
我们可以将每个点的 dis 初值都赋成 0, 我们对每个的点都进行 DFS, 在所有的起始点我们都只遍历边权为负的边, 因为每个的点的 dis 初始都是 0, 最先找到的边是负权,接着往深处遍历的时候,只找和为负权的路径,这样,我们的 DFS 只会遍历负权路径,有很多的边我们就优化掉了。
这里给出此题的代码,在 POJ 上加上普通的就可以跑 16 ms,还是比较好些。
#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <cmath>#include <ctime>#include <map>#include <vector>#define clr(a) memset(a, 0, sizeof(a))using namespace std;inline int read() { int i = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { i = (i << 3) + (i << 1) + ch - '0'; ch = getchar(); } return i * f;}const int MAXN = 500 + 5;const int MAXM = 3000 + 5;int first[MAXN], nxt[MAXM * 2], to[MAXM * 2], len[MAXM * 2];int tot, dis[MAXN], vis[MAXN], flag;inline void addedge(int x, int y, int w) { nxt[++tot] = first[x]; first[x] = tot; to[tot] = y, len[tot] = w;}inline void Dfs_spfa(int x) { vis[x] = 1; for(int i = first[x]; i; i = nxt[i]) { int v = to[i]; if(flag) return ; if(dis[v] > dis[x] + len[i]) { dis[v] = dis[x] + len[i]; if(vis[v]) { flag = 1; return; } else Dfs_spfa(v); } } vis[x] = 0;}int main() { int t = read(); while(t--) { clr(dis), clr(vis), clr(first); clr(nxt);tot = 0; int n = read(), m = read(), w = read(); for(int i = 1; i <= m; ++i) { int x = read(), y = read(), z = read(); addedge(x, y, z); addedge(y, x, z); } for(int i = 1; i <= w; ++i) { int x = read(), y = read(), z = read(); addedge(x, y, -z); } flag = 0; for(int i = 1; i <= n; ++i) { if(flag) break; Dfs_spfa(i); } if(flag) printf("YES\n"); else printf("NO\n"); }}
- POJ3259 判断是否存在负权环
- POJ3259 Wormholes 【Bellmanford判断是否存在负回路】
- [模板]poj3259(判断是否存在负环)
- POJ3259(判断有无负权环)
- poj 3259 判断是否存在负权环
- 判断文件是否存在
- 判断文件夹是否存在
- 判断用户是否存在
- 判断文件是否存在
- 判断对象是否存在
- 判断文件夹是否存在
- 判断文件是否存在
- 判断表是否存在
- 判断文件是否存在
- 判断字段是否存在
- 判断URL是否存在
- 判断URL是否存在
- 判断表是否存在
- 0x5f3759df的数学原理 ----一种快速开方根求倒原理
- JS阻止事件冒泡兼容各浏览器
- 分布式系统的高效运维要点
- 截取视频图片
- poj 1236 Network of Schools 强连通分量
- POJ3259 判断是否存在负权环
- CCF-20161201-中间数(100分)
- 通过 SSH 实现 TCP / IP 隧道(端口转发)
- SGeo中国中心:开源GIS软件、在线教程、数据相关资料
- Servlet (六 Session)
- 欢迎使用CSDN-markdown编辑器
- 第3章 数据的输入与输出
- Python网络数据采集总结——未完待续
- Tensorboard命令未找到问题的解决