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 N (1 ≤ N ≤ 500) fields conveniently numbered 1..N, M (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.
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 F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.
Input
Output
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
/* * POJ 3259 * 判断图中是否存在负环回路。 * 为了防止图不连通的情况,增加一个点作为起点,这个点和其余的点都相连,且距离为0。 */ #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <cmath> #include <queue> #include <map> #include <set> #define eps 1e-9 using namespace std; /* * 单源最短路bellman_ford算法,复杂度O(VE) * 可以处理负边权图。 * 可以判断是否存在负环回路。返回true,当且仅当图中不包含从源点可达的负权回路 * vector<Edge>G;先G.clear()初始化,然后加入所有边 * 假设图不存在负环,那么最短路最多经过(起点不算)n-1个结点,可以通过"n-1"轮松弛操作得到最短路; * 点的编号从1开始(从0开始简单修改就可以了) */ typedef long long ll; typedef pair<int,int>P; const int M = 600; const int INF = 0x3f3f3f3f; const int mod = 10000007; int d[M]; struct Edge { int u,v,c; Edge(int _u = 0,int _v = 0,int _c = 0):u(_u),v(_v),c(_c) {} }; vector<Edge>G; bool bellman_ford(int start,int n) { //点的编号从1开始 for(int i = 1; i <= n; i++) d[i] = INF; d[start] = 0; for(int i = 1; i < n; i++) { //最多松弛n-1次 bool flag = true; for(int j = 0; j < G.size(); j++) { if(d[G[j].v] > d[G[j].u] + G[j].c) { flag = false; d[G[j].v] = d[G[j].u] + G[j].c; } } if(flag) return true; //没有负环回路 } for(int i = 0; i < G.size(); i++) { if(d[G[i].v] > d[G[i].u] + G[i].c) return false; //有负环回路 } return true; //没有负环回路 } int main() { int T,n,m,w; cin>>T; while(T--) { G.clear(); scanf("%d %d %d",&n,&m,&w); for(int i = 0; i < m; i++) { int u,v,c; scanf("%d %d %d",&u,&v,&c); G.push_back(Edge(u,v,c)); G.push_back(Edge(v,u,c)); } for(int i = 0; i < w; i++) { int u,v,c; scanf("%d %d %d",&u,&v,&c); G.push_back(Edge(u,v,-c)); } for(int i = 1; i <= n; i++) { G.push_back(Edge(n + 1,i,0)); } if(bellman_ford(n + 1,n + 1)) puts("NO"); else puts("YES"); } return 0; }
POJ 3259 Wormholes(最短路,判断有没有负环回路)
原文地址:http://blog.csdn.net/zsgg_acm/article/details/43732657