poj3259_bellman-ford

题意:famer给出一些fields,paths,wormholes.其中paths是fields之间的双向正权值边,wormholes是fields之间的单向负权边。求在这个图中是否存在权值为负的回路。

这个题用的是bellman_ford算法。其中有一下几个问题:

1.在描述Paths时,a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path. 当时没有看到是双向边,WA了。还有,我没有对后半句处理,也过了。

2.一开始以第一个点为源点进行bellman-ford,结果WA了。后来发现,bellman-ford可以得出是否存在着一个从源点可达的权为负的回路。而本题是要求在图中是否存在环。因此需要对未处理过的点进行遍历进行bellman-ford。或者是看到网上有种做法是,初始化每个节点的d值为0或者某一个数这样也可以判断图中是否存在某个负权的环。这种做法类似差分约束引入顶点v0,保证从v0可到每个顶点。权值为0,直接赋给d[i]就可以了

3.一点小的优化,bellman-ford中进行n-1次遍历的时候可以设置标志flag,如果某次遍历中flag没有变化的时候,就可以终止。跟冒泡排序的思想一样。

代码:

View Code
  1 #include <iostream>
  2 #include <stdio.h>
  3 using namespace std;
  4 const int maxe=5210;
  5 const int maxp=505;
  6 const int maxnum=10005;
  7 int p,m,w;
  8 struct edge
  9 {
 10     int v;
 11     int w;
 12     int next;
 13 }edge[maxe];
 14 
 15 typedef struct
 16 {
 17     int d;
 18     int pre;
 19 }pp;
 20 pp point[maxp];
 21 
 22 void Init()
 23 {
 24     int i;
 25     for(i=1;i<=p;i++)
 26     {
 27         point[i].d=0;  //全都置为0
 28         point[i].pre=-1;
 29     }
 30     int u,v,weight;
 31     int index=1;
 32     for(i=1;i<=m;i++)
 33     {
 34         scanf("%d%d%d",&u,&v,&weight);
 35         edge[index].v=v;
 36         edge[index].w=weight;
 37         edge[index].next=point[u].pre;
 38         point[u].pre=index;
 39         index++;
 40 
 41         edge[index].v=u;
 42         edge[index].w=weight;
 43         edge[index].next=point[v].pre;
 44         point[v].pre=index;
 45         index++;
 46     }
 47     for(i=1;i<=w;i++)
 48     {
 49         scanf("%d%d%d",&u,&v,&weight);
 50         edge[index].v=v;
 51         edge[index].w=-1*weight;
 52         edge[index].next=point[u].pre;
 53         point[u].pre=index;
 54         index++;
 55     }
 56 }
 57 
 58 void traversal()
 59 {
 60     int i,j;
 61     for(i=1;i<=p;i++)
 62         for(j=point[i].pre;j!=-1;j=edge[j].next)
 63             cout<<i<<" "<<edge[j].v<<" "<<edge[j].w<<endl;
 64 }
 65 
 66 bool bellman_ford()
 67 {
 68     int i,j,k;
 69     bool flag;
 70     for(k=1;k<=p-1;k++)
 71     {
 72         flag=false;
 73         for(i=1;i<=p;i++)
 74             for(j=point[i].pre;j!=-1;j=edge[j].next)
 75             {
 76                 int v,w;
 77                 v=edge[j].v;
 78                 w=edge[j].w;
 79                 if(point[i].d==maxnum) continue;
 80                 else if(point[v].d>point[i].d+w)
 81                 {
 82                     point[v].d=point[i].d+w;
 83                     flag=true;
 84                 }
 85             }
 86         if(!flag)
 87             break;
 88     }
 89 
 90     for(i=1;i<=p;i++)
 91         for(j=point[i].pre;j!=-1;j=edge[j].next)
 92             if(point[edge[j].v].d>point[i].d+edge[j].w)
 93                 return false;
 94     return true;
 95 }
 96 
 97 int main()
 98 {
 99     int num;
100     bool flag;
101     scanf("%d",&num);
102     while(num--)
103     {
104         scanf("%d%d%d",&p,&m,&w);
105         Init();
106         //cout<<endl;
107         //traversal();
108         //point[1].d=0;
109         flag=bellman_ford();
110         if(flag)
111             printf("NO\n");
112         else
113             printf("YES\n");
114     }
115     return 0;
116 }

tju oj 2831

下面是遍历的做法,但不知道为什么不过?

View Code
  1 #include <iostream>
  2 #include <stdio.h>
  3 #define white 0
  4 #define black 1
  5 using namespace std;
  6 const int maxe=5210;
  7 const int maxp=505;
  8 const int maxnum=10005;
  9 int p,m,w;
 10 struct edge
 11 {
 12     int v;
 13     int w;
 14     int next;
 15 }edge[maxe];
 16 
 17 typedef struct
 18 {
 19     int d;
 20     int color;
 21     int pre;
 22 }pp;
 23 pp point[maxp];
 24 bool f;
 25 
 26 void Init()
 27 {
 28     int i;
 29     for(i=1;i<=p;i++)
 30     {
 31         point[i].d=maxnum;  //全都置为0
 32         point[i].pre=-1;
 33         point[i].color=white;
 34     }
 35     int u,v,weight;
 36     int index=1;
 37     for(i=1;i<=m;i++)
 38     {
 39         scanf("%d%d%d",&u,&v,&weight);
 40         edge[index].v=v;
 41         edge[index].w=weight;
 42         edge[index].next=point[u].pre;
 43         point[u].pre=index;
 44         index++;
 45 
 46         edge[index].v=u;
 47         edge[index].w=weight;
 48         edge[index].next=point[v].pre;
 49         point[v].pre=index;
 50         index++;
 51     }
 52     for(i=1;i<=w;i++)
 53     {
 54         scanf("%d%d%d",&u,&v,&weight);
 55         edge[index].v=v;
 56         edge[index].w=-1*weight;
 57         edge[index].next=point[u].pre;
 58         point[u].pre=index;
 59         index++;
 60     }
 61 }
 62 
 63 void traversal()
 64 {
 65     int i,j;
 66     for(i=1;i<=p;i++)
 67         for(j=point[i].pre;j!=-1;j=edge[j].next)
 68             cout<<i<<" "<<edge[j].v<<" "<<edge[j].w<<endl;
 69 }
 70 
 71 void bellman_ford(int u)
 72 {
 73     point[u].d=0;
 74     point[u].color=black;
 75     int i,j,k;
 76     bool flag;
 77     for(k=1;k<=p-1;k++)
 78     {
 79         flag=false;
 80         for(i=1;i<=p;i++)
 81             for(j=point[i].pre;j!=-1;j=edge[j].next)
 82             {
 83                 int v,w;
 84                 v=edge[j].v;
 85                 point[v].color=black;
 86                 w=edge[j].w;
 87                 if(point[i].d==maxnum) continue;
 88                 else if(point[v].d>point[i].d+w)
 89                 {
 90                     point[v].d=point[i].d+w;
 91                     flag=true;
 92                 }
 93             }
 94         if(!flag)
 95             break;
 96     }
 97 
 98     for(i=1;i<=p;i++)
 99         for(j=point[i].pre;j!=-1;j=edge[j].next)
100             if(point[edge[j].v].d>point[i].d+edge[j].w)
101             {
102                 f=false;
103                 return ;
104             }
105     f=true;
106 }
107 
108 int main()
109 {
110     int num,i;
111     scanf("%d",&num);
112     while(num--)
113     {
114         scanf("%d%d%d",&p,&m,&w);
115         Init();
116         //cout<<endl;
117         //traversal();
118         //point[1].d=0;
119         f=true;
120         for(i=1;i<=p;i++)
121         {
122             if(!f)  break;
123             if(point[i].color==white)
124                 bellman_ford(i);
125         }
126         if(f)
127             printf("NO\n");
128         else
129             printf("YES\n");
130     }
131     return 0;
132 }

 

posted @ 2012-08-02 20:02  pushing my way  阅读(257)  评论(0编辑  收藏  举报