暑假训练专题三 bellman-ford 求两点之间的最短路径

 bellman-ford 求两点之间的最短路径  点数为v,边数为e,点的距离设为dis[i];

1.开始对所有的点初始为最大值,所求的源点的值设为0;

2.开个结构体数组(邻接矩阵)来存储所有的边的两点和权值(from,to,value)

3.循环1- v  实际循环1到 v-1次以内 是正确的结果,表示没有负环,如果循环了v次,则表示存在负环。(判断的是dis[to]>dis[from]+value{dis[to]=dis[from]+value;})

4.最后输出个点的结果 。

 

 方案一:如果要求b点到其余各点的距离,就将b点的距离设为0;并且可以求出来是否存在负环。 

 方案二: 如果初始化所有的的为inf  仅能求出是否有负环

这道题采用的是方案二:

下面是一道经典例题:

http://poj.org/problem?id=3259

wormholes

得出正确的结果:

postcode:

#include<stdio.h>
const int max=10000000;
typedef structnode {
                     int from;
                     int to;
                     int value;
                    } point;
pointp[5500];

int dis[510];
void init(); 
int judge();

int t,n,m,w,i,j,x,y,z,result;
int main()
{

  scanf("%d",&t);
  while(t--)
  {
     scanf("%d %d %d",&n,&m,&w);
     init();   
                 
     for(i=1;i<=m;i++)
     {
       
       scanf("%d %d %d",&x,&y,&z);
       p[i].from=p[i+m].to=x;
       p[i].to=p[i+m].from=y;    
       p[i].value=p[i+m].value=z;   
                  
     }
  
     for(i=2*m+1;i<=2*m+w;i++)
     {
      scanf("%d %d %d",&x,&y,&z);  
       p[i].from=x;
       p[i].to=y;
       p[i].value=-z;
                       
     } 
     result=judge();
     if(result==0)printf("YES\n");
     else printf("NO\n");
  }      
}


void init()
{int i;
  for(i=1;i<=n;i++)
  {
   dis[i]=max;
  }   
}
int judge()
{
  int flag;
  for(i=1;i<=n;i++)
  {
    flag=0;
    for(j=1;j<=2*m+w;j++)
    {
     if(dis[p[j].to]>dis[p[j].from]+p[j].value){
    dis[p[j].to]=dis[p[j].from]+p[j].value;
          flag=1;
                                               }
    }
    if(flag==1&&i==n)return 0;
    if(flag==0)return 1;  
  }
   
     
}

  

方案一的代码:
bool Bellman(int s , int n , int m){
    int u , v , w , i , j , flag;
    for(i = 1 ; i <= n ; i ++)dis[i] = INF;
    dis[s] = 0;
    for(i = 1 ; i <= n ; i ++){
        for(j = flag = 0 ; j < m ; j ++){
            u = edge[j].from , v = edge[j].to , w = edge[j].value;
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u] + w;
                flag = 1;
            }
        }
        if(!flag)break;
        if(i == n && flag)return false;
    }
    return true;
}

 



转载于:https://www.cnblogs.com/ysh-blog/archive/2012/07/04/2575786.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值