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 }