Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 27964 | Accepted: 10058 |
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
解题思路:首先,应知道图不一定是连通的,只有图中存在负环就输出“YES”。因此,用spfa算法时,如果一次从源点的松弛不能到达所有边,必须把剩下的再用一次spfa算法。
#include<stdio.h> #include<string.h> #include<queue> using namespace std; #define N 505 const int inf=10005; int map[N][N]; //记录点之间关系 int dis[N]; //记录当前点到源点的距离 int mark[N]; //标记该点是否在队列内 int num[N],n; //记录一次搜索中某点入队的次数 int Min(int a,int b) { return a<b?a:b; } int spfa() { int i,s=1; queue<int>q; memset(num,0,sizeof(num)); while(1) { if(q.empty()) { for(i=1;i<=n;i++) if(!num[i]) //若源点没有和所有的点连通, break; if(i<=n) { q.push(i); //则把后面的点入队,在进行一次spfa算法 memset(mark,0,sizeof(mark)); memset(num,0,sizeof(num)); for(;i>0;i--) num[i]=1; //先把前面的不可到点标记 } else return 0; } s=q.front(); q.pop(); mark[s]=0; for(i=1;i<=n;i++) { if(dis[i]>dis[s]+map[s][i]) { dis[i]=dis[s]+map[s][i]; if(!mark[i]) { mark[i]=1; num[i]++; q.push(i); if(num[i]>n) //存在负环 return 1; } } } } return 0; } int main() { int T,a,b,c,m,w,i,j; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&w); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) map[i][j]=inf; dis[i]=inf; } while(m--) { scanf("%d%d%d",&a,&b,&c); map[a][b]=Min(map[a][b],c); //两点存在多条路 map[b][a]=Min(map[b][a],c); //bidirectional双向边 } while(w--) { scanf("%d%d%d",&a,&b,&c); map[a][b]=Min(map[a][b],0-c); } if(spfa()) printf("YES\n"); else printf("NO\n"); } return 0; }
poj 3259 Wormholes,布布扣,bubuko.com
原文:http://blog.csdn.net/u011721440/article/details/23459893