~题目链接~
http://poj.org/problem?id=3259
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
题目:输入农田个数,连通的路数,虫洞的个数。两农田之间连通是双向的,而虫洞是单向的。虫洞有这样的性质:可是时间倒流。问你这个农民能不能看到他自己,也就是说,有没有这样一条路径,能利用虫洞的时间倒流的性质,让这个人能在这个点出发前回去,这样他就是能看到他自己了。
1.Bellmen_ford

1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #define maxn 0x7ffffff 5 6 struct node 7 { 8 int u,v,w; 9 } map[10010]; 10 int h,num[1010]; 11 12 void cap(int u,int v,int w) 13 { 14 h++; 15 map[h].u=u; 16 map[h].v=v; 17 map[h].w=w; 18 } 19 20 int bellmen_ford(int n) 21 { 22 int i,j; 23 for(i=1; i<=n; i++)//初始化 24 num[i]=maxn; 25 for(i=0; i<n; i++)//迭代n次 26 for(j=1; j<=h; j++)//检查每一条边 27 if(num[map[j].v]>num[map[j].u]+map[j].w)//松弛 28 num[map[j].v]=num[map[j].u]+map[j].w; 29 for(i=1; i<=h; i++)//检查是否存在负权回路 30 if(num[map[i].v]>num[map[i].u]+map[i].w) 31 return 1; 32 return 0; 33 } 34 35 int main() 36 { 37 int T; 38 scanf("%d",&T); 39 while(T--) 40 { 41 int n,m,k,u,v,w,i; 42 h=0; 43 scanf("%d%d%d",&n,&m,&k); 44 for(i=0; i<m; i++) 45 { 46 scanf("%d%d%d",&u,&v,&w); 47 cap(u,v,w); 48 cap(v,u,w); 49 } 50 for(i=0; i<k; i++) 51 { 52 scanf("%d%d%d",&u,&v,&w); 53 cap(u,v,-w); 54 } 55 if(bellmen_ford(n)) 56 printf("YES "); 57 else 58 printf("NO "); 59 } 60 61 return 0; 62 }
2.Spfa

1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<queue> 5 #define maxn 0x7ffffff 6 #define maxm 1000+10 7 8 using namespace std; 9 10 int map[maxm][maxm],dis[maxm]; 11 queue<int>Q; 12 13 int spfa(int n) 14 { 15 while(!Q.empty()) 16 Q.pop(); 17 int num[maxm],flag[maxm],i; 18 memset(num,0,sizeof(num)); 19 memset(flag,0,sizeof(flag)); 20 for(i=1; i<=n; i++) 21 dis[i]=maxn; 22 Q.push(1); 23 dis[1]=0; 24 num[1]=1; 25 flag[1]=1; 26 while(!Q.empty()) 27 { 28 int h=Q.front(); 29 Q.pop(); 30 flag[h]=0; 31 for(i=1; i<=n; i++) 32 if(dis[i]>dis[h]+map[h][i]) 33 { 34 dis[i]=dis[h]+map[h][i];//松弛 35 if(!flag[i]) 36 { 37 Q.push(i); 38 flag[i]=1; 39 num[i]++; 40 if(num[i]>=n)//判断负权回路只需要入队次数大于顶点数就行了 41 return 1; 42 } 43 } 44 } 45 return 0; 46 } 47 48 int main() 49 { 50 int T; 51 scanf("%d",&T); 52 while(T--) 53 { 54 int n,m,k,u,v,w,i; 55 scanf("%d%d%d",&n,&m,&k); 56 for(i=0; i<m; i++) 57 { 58 scanf("%d%d%d",&u,&v,&w); 59 map[u][v]=map[v][u]=w; 60 } 61 for(i=0; i<k; i++) 62 { 63 scanf("%d%d%d",&u,&v,&w); 64 map[u][v]=-w; 65 } 66 if(spfa(n)) 67 printf("YES "); 68 else 69 printf("NO "); 70 } 71 72 return 0; 73 }