poj_3259_bellman-ford

题目描述:

   有n个点,2m条正权路,w条负权路,求能不能从其中一个点进入,回到自己时走过的路径为负值。

 

解题思路:

   归结为bellman-ford问题。bellman建立在求无负权值回路的最短路径问题上,如果在外层的第n次循环还有点值更新,就说明存在负权值回路,既不能收敛。——这个问题就是检查这个图是否存在负权值回路。

   注意:普通路径是双向的!所以数组大小一定要开够。

 

代码:

#include <stdio.h>
#include <stdlib.h>
#define N 1001
#define M 6000
#define MAX 2000000000

typedef struct{
   int s;
   int e;
   int t;
}Edge;

Edge edge[M];
int Farm[N][N], D[N];
int n,m,w;

int bellman_ford()
{
   int i,j,f;
   for(i=2;i<=n;i++)
   {
      f = 0;
      for(j=1;j<=2*m+w;j++)
      {
         if(D[edge[j].s]<MAX && D[edge[j].e] > D[edge[j].s]+edge[j].t)
         {
            f = 1;
            D[edge[j].e] = D[edge[j].s]+edge[j].t;
         }
      }
      if(0 == f)
         return 1;
   }
   for(j=1;j<=2*m+w;j++)
   {
      if(D[edge[j].s]<MAX && D[edge[j].e] > D[edge[j].s]+edge[j].t)
         return 0;
   }
   return 1;
}

main()
{
   int t,f,i;
   scanf(“%d”,&t);
   while(t>0)
   {
      scanf(“%d %d %d”,&n, &m, &w);
      for(i=1;i<=2*m;i=i+2)
      {
         scanf(“%d %d %d”,&edge[i].s,&edge[i].e,&edge[i].t);
         edge[i+1].s = edge[i].e;
         edge[i+1].e = edge[i].s;
         edge[i+1].t = edge[i].t;
      }
      for(i=2*m+1;i<=2*m+w;i++)
      {
         scanf(“%d %d %d”,&edge[i].s,&edge[i].e,&edge[i].t);
         edge[i].t = 0 – edge[i].t;
      }
      for(i=1;i<=n;i++)
         D[i] = MAX;
      D[1] = 0;
      f = bellman_ford();
      if(1 == f)//没有负权回路
         printf(“NO\n”);
      else
         printf(“YES\n”);
      t–;
   } 
  
   //system(“pause”);
   return 0;
}

 

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/u010456139/article/details/8874731
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞