POJ_3250_Wormholes(Bellman-Ford算法)

代码1:

/*
bellman-ford算法适合单源路径算法,和负权回路。

因此算法核心就是松弛操作

*/

 1 /*
 2 bellman-ford算法适合单源路径算法,和负权回路。
 3 */
 4 # include<stdio.h>
 5 # include <string.h>
 6 using namespace std;
 7 int d[1001];          //源点到各点权值
 8 int max_w=10001;      //无穷远
 9 struct node
10 {
11     int s;
12     int e;
13     int t;
14 }edge[5200];
15 int N,M,W_h;
16 int all_e;            //所有的边数。
17 bool bellman()
18 {
19     bool flag;
20     for(int i=0;i<N-1;i++) //为什么是N-1,因为对于N个结点的图最多有N-1个结点可能对其执行松弛操作。
21     {
22         flag=false;
23         for(int j=0;j<all_e;j++)
24             if(d[edge[j].e] > d[edge[j].s] + edge[j].t)
25             {
26                 d[edge[j].e] = d[edge[j].s] + edge[j].t;
27                 flag=true;         //relax对路径有更新
28             }
29         if(!flag)   
30             break;  //只要某一次relax没有更新,说明最短路径已经查找完毕,
31                     //或者部分点不可达,可以跳出循环(releax),或者直接返回false。
32     }
33 //    if(!flag)
34 //        return false;
35     for(int k=0;k<all_e;k++) //如果还能进行松弛操作,说明有负权回路。
36         if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t)
37             return true;
38         return false;
39 }
40 int main(void)
41 {
42     int u,v,w;
43     int F;
44     cin>>F;
45     while(F--)
46     {
47         memset(dis,max_w,sizeof(dis));    //源点到各点的初始值为无穷,即默认不连通
48         cin>>N>>M>>W_h;
49         all_e=0;  
50         //双向边赋值。
51         for(int i=1;i<=M;i++)
52         {
53             cin>>u>>v>>w;
54             edge[all_e].s=edge[all_e+1].e=u;
55             edge[all_e].e=edge[all_e+1].s=v;
56             edge[all_e++].t=w;
57             edge[all_e++].t=w;  
58         }
59         //单向边赋值。
60         for(int j=1;j<=W_h;j++)
61         {
62             cin>>u>>v>>w;
63             edge[all_e].s=u;
64             edge[all_e].e=v;
65             edge[all_e++].t=-w;     //注意权值为负
66         }
67         if(bellman())
68             cout<<"YES"<<endl;
69         else
70             cout<<"NO"<<endl;
71     }
72     return 0;
73 }
View Code

代码二:

用上一题的思路

http://www.cnblogs.com/liun1994/articles/3257344.html

/*这里源点的时间用0来标记,那么在以后的操作中,我只要能找到那么一个回路能使得源点变成<0就说明能够穿越。*/

 1 /*
 2 想不起来什么意思就画图看一下。
 3 */
 4 # include <string.h>
 5 #include<iostream>
 6 using namespace std;
 7 int dis[1001];   
 8 int max_w=10001;  
 9 struct node
10 {
11     int s;
12     int e;
13     int t;
14 }edge[5200];
15 int N,M,W_h; 
16 int all_e;
17 
18 bool bellman(void)
19 {
20     bool flag;
21     dis[1]=0;
22     while(dis[1] >= 0)//当找到比他小的时候就退出,说明肯定能够穿越
23     {
24         flag=false;
25         for(int j=0;j<all_e;j++)
26             if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t)
27             {
28                 dis[edge[j].e] = dis[edge[j].s] + edge[j].t;
29                 flag=true;  
30             }
31             if(!flag)   //如果找一圈之后没有可以改变的了,说明已经找到头了,直接比较即可。
32                 return dis[1]<0 ? 1:0;
33     }
34     return 1;
35 }
36 int main(void)
37 {
38     int u,v,w;
39     int F;
40     cin>>F;
41     while(F--)
42     {
43         memset(dis,1000000,sizeof(dis));   //源点到各点的初始值为无穷,即默认不连通    
44         cin>>N>>M>>W_h;
45         all_e=0; 
46         for(int i=1;i<=M;i++)
47         {
48             cin>>u>>v>>w;
49             edge[all_e].s=edge[all_e+1].e=u;
50             edge[all_e].e=edge[all_e+1].s=v;
51             edge[all_e++].t=w;
52             edge[all_e++].t=w;          
53         }
54         for(int j=1;j<=W_h;j++)
55         {
56             cin>>u>>v>>w;
57             edge[all_e].s=u;
58             edge[all_e].e=v;
59             edge[all_e++].t=-w;  
60         }    
61         if(bellman())
62             cout<<"YES"<<endl;
63         else
64             cout<<"NO"<<endl;
65     }
66     return 0;
67 }
View Code

 

 

posted on 2013-08-14 19:18  随风浪子的博客  阅读(156)  评论(0编辑  收藏  举报

导航