POJ 3259 Wormholes

最短路问题。这个题也够DT。。出题者真会YY。

题目链接http://poj.org/problem?id=3259

两个算法。一个是bellman-ford一个就是他的队列实现。也就是对他的优化spfa算法。

bellman-ford算法

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define INF 1000000
 4 int N,F,M,W,en;//N 农场个数,F 农田个数 M路径条数 W虫洞个数 en边数
 5 int dist[510];
 6 typedef struct node
 7 {
 8     int u,v;//边的两个端点
 9     int w;//权值
10 }EDGE;
11 EDGE e[INF];
12 void bellman()
13 {
14     int i,j,flag;
15     for(i=0;i<N-1;i++)
16     {
17         flag=0;
18         for(j=0;j<en;j++)
19     {
20     if (dist[e[j].v] > dist[e[j].u]+e[j].w)
21     {
22     flag=1;
23     dist[e[j].v] = dist[e[j].u]+e[j].w;
24     }
25     }
26     }
27     for(j=0;j<en;j++)
28     {
29      if(dist[e[j].v]>dist[e[j].u]+e[j].w)
30      {
31          printf("YES\n");
32          return;
33      }
34     }
35     printf("NO\n");
36 
37 }
38 int main()
39 {
40     int i;
41     scanf("%d",&F);
42     while(F--)
43     {
44         memset(dist,INF,sizeof(dist));
45         en=0;
46         scanf("%d%d%d",&N,&M,&W);
47         for(i=0;i<M;i++)
48         {
49             scanf("%d%d%d",&e[en].u,&e[en].v,&e[en].w);
50             en++;
51             e[en].u=e[en-1].v;
52             e[en].v=e[en-1].u;
53             e[en].w=e[en-1].w;
54             en++;
55         }
56        for (i=0;i<W;i++)
57      {
58       scanf("%d%d%d",&e[en].u,&e[en].v,&e[en].w); //虫洞路径  u, v, 以及倒流的时间
59       e[en].w=-e[en].w;
60        en++;
61      }
62      bellman();
63     }
64     return 0;
65 }

spfa算法

View Code
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<math.h>
 5 #include<queue>
 6 #include<string.h>
 7 #define Max 0xfffffff
 8 using namespace std;
 9 const int N=505;
10 int path[505][505];//边距
11 int dist[505];//到原点距离
12 bool spfa(int n)
13 {
14     queue<int>str;
15     bool in[N];
16     int num[N];
17     memset(in,false,sizeof(in));//是否在队列中
18     memset(num,0,sizeof(num));//进队列次数
19     for(int i=1;i<=n;++i)//初始化
20     dist[i]=Max;
21     dist[1]=0;
22     str.push(1);
23     in[1]=true;
24     num[1]=1;
25     while(!str.empty())//队列是否为空 如果队列一直到空 则说明没有负环
26     {
27         int x=str.front();
28         str.pop();
29         in[x]=false;
30         for(int i=1;i<=n;++i)
31         {
32             if(dist[i]>dist[x]+path[x][i])//找可更新点
33             {
34                 dist[i]=dist[x]+path[x][i];
35                 if(in[i]==false)//如果可更新点不再队列中
36                 {
37                     str.push(i);//进队列
38                     in[i]=true;//标记
39                     num[i]++;//进队列次数
40                     if(num[i]==n)//进队列此次到达n  说明有负环
41                     return true;
42                 }
43             }
44         }
45     }
46     return false;
47 }
48 int main()
49 {
50    // freopen("data.txt","r",stdin);
51     int n,m,w;
52     int i,j,l;
53     int f;
54     cin>>f;
55     while(f--)
56     {
57         cin>>n>>m>>w;
58          for(i=1;i<=n;i++)
59         {
60             for(j=i;j<=n;j++)
61             {
62                 path[i][j]=path[j][i]=Max;
63             }
64         }
65         while(m--)
66         {
67            cin>>i>>j>>l;
68            if(l<path[i][j])
69            {
70                path[i][j]=path[j][i]=l;
71            }
72         }
73         while(w--)
74         {
75             cin>>i>>j>>l;
76             if((-l)<path[i][j])
77             {
78                 path[i][j]=(-l);
79             }
80         }
81         if(spfa(n)==true)
82         printf("YES\n");
83         else
84         printf("NO\n");
85     }
86     return 0;
87 }

 

posted @ 2012-08-15 20:47  时光旅行的懒猫  阅读(200)  评论(0编辑  收藏  举报