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 }

 

你可能感兴趣的:(poj)