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
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 #define INF 0x3f3f3f3f 6 #define maxs 10010 7 using namespace std; 8 struct node 9 { 10 int to; 11 int w; 12 } t; 13 vector<node>Map[maxs]; 14 int dis[maxs]; 15 int vis[maxs]; 16 int n,m,k; 17 void add(int s,int e,int w) 18 { 19 t.to=e; 20 t.w=w; 21 Map[s].push_back(t); 22 } 23 void init() 24 { 25 int i; 26 memset(dis,INF,sizeof(dis)); 27 memset(vis,0,sizeof(vis)); 28 for(i=0; i<=n; i++) 29 { 30 Map[i].clear(); 31 } 32 } 33 int SPFA(int s) 34 { 35 int cnt[maxs]= {0};///记录每个点入队次数 36 int i; 37 dis[s]=0; 38 vis[s]=1; 39 queue<int>q; 40 q.push(s); 41 cnt[s]++; 42 while(!q.empty()) 43 { 44 int u=q.front(); 45 /*if(cnt[u]>=n) 46 { 47 return 0;///这里用来判断入队列是否超过N次 48 }*/ 49 q.pop(); 50 vis[u]=0; 51 for(i=0; i<Map[u].size(); i++) 52 { 53 int to=Map[u][i].to; 54 if(dis[to]>dis[u]+Map[u][i].w) 55 { 56 dis[to]=dis[u]+Map[u][i].w;///松弛操作 57 if(dis[1]<0)///这种判断是否有负环的更快。如果起始点的dis[s]<0说明存在负环 58 { 59 return 0; 60 } 61 if(!vis[to]) 62 { 63 vis[to]=1; 64 q.push(to); 65 cnt[to]++; 66 } 67 } 68 } 69 } 70 return 1; 71 } 72 int main() 73 { 74 int t,i,j,u,v,w; 75 scanf("%d",&t); 76 for(i=1; i<=t; i++) 77 { 78 scanf("%d%d%d",&n,&m,&k); 79 init(); 80 while(m--) 81 { 82 scanf("%d%d%d",&u,&v,&w); 83 add(u,v,w); 84 add(v,u,w); 85 } 86 while(k--) 87 { 88 scanf("%d%d%d",&u,&v,&w); 89 add(u,v,-w);///虫洞时间取负值 90 } 91 if(SPFA(1)) 92 { 93 printf("NO "); 94 } 95 else 96 { 97 printf("YES "); 98 } 99 } 100 return 0; 101 }
这里再附上使用邻接矩阵和Bellman-Ford算法的代码。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define inf 0x3f3f3f3f struct Edge { int f;///起点 int t;///终点 int c;///距离 } edge[6000]; int dist[505]; int n,m,h,cnt; int bellman_ford() { memset(dist,inf,sizeof(dist)); dist[1]=0;///起点 int i,j; for(j=1; j<=n; j++) { for(i=1; i<=cnt; i++) { if(dist[edge[i].t]>dist[edge[i].f]+edge[i].c)///松弛操作 { dist[edge[i].t]=dist[edge[i].f]+edge[i].c; } } } int flag=1; for(i=1; i<=cnt; i++)///遍历所有的边 { if(dist[edge[i].t]>dist[edge[i].f]+edge[i].c) { flag=0;///存在从源点可达的负权回路 break; } } return flag; } int main() { int i,t; scanf("%d",&t); while(t--) { cnt=0; scanf("%d %d %d",&n,&m,&h); int u,v,w; for(i=1; i<=m; i++) { cnt++; scanf("%d %d %d",&u,&v,&w); edge[cnt].f=u; edge[cnt].t=v; edge[cnt].c=w; cnt++; edge[cnt].f=v; edge[cnt].t=u; edge[cnt].c=w; } for(i=1; i<=h; i++) { cnt++; scanf("%d %d %d",&u,&v,&w); edge[cnt].f=u; edge[cnt].t=v; edge[cnt].c=-w; } if(bellman_ford()) printf("NO "); else printf("YES "); } return 0; }