Wormholes(POJ 3259)

~题目链接~

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\n");
57         else
58             printf("NO\n");
59     }
60 
61     return 0;
62 }
View Code

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\n");
68         else
69             printf("NO\n");
70     }
71 
72     return 0;
73 }
View Code

 

posted @ 2013-08-14 15:14  Locke_Q  阅读(211)  评论(0编辑  收藏  举报