bellman-ford算法求最短路小结【以HDU2544为例】

1.初始化:s为源点时d[s]=0,d[x]=inf(x!=s)【inf是正无穷大】
2.迭代n-1次后还能继续松弛,说明存在负环
并且在第n次更新中可以通过断点找出回路(n为顶点数量)
3.对于有向图,松弛操作只需要松弛一条边的一端
无向图两边同时松弛!
注意!!无向图的松弛操作比有向图多出一个端点
松弛的原则是:u->v这条边,用dis[u]推导dis[v]的值 

 下面我们以HDU2544的最短路题目为例,附上代码以供参考

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=105;
const int maxm=10005;
int n,m,a,b,t;
int v[maxm],u[maxm];//保存边两条连接的顶点序号
int w[maxm];//保存边的权值
int dis[maxn];//保存最短路径结果
void init()
{
    memset(v,-1,sizeof(v));
    memset(u,-1,sizeof(u));
    memset(w,inf,sizeof(w));
    memset(dis,inf,sizeof(dis));
    dis[1]=0;
}
void bellman_ford()
{
    for(int i=0; i<n-1; i++) //对所有边更新n-1次
    {
        int flag=1;//如果在当前一轮中没有松弛,说明全部结点都达到最短路径,跳出循环即可
        for(int j=0; j<m; j++)
            if(dis[u[j]]>dis[v[j]]+w[j])
            {
                dis[u[j]]=dis[v[j]]+w[j];
                flag=0;
            }
        for(int j=0; j<m; j++)
            if(dis[v[j]]>dis[u[j]]+w[j])
            {
                dis[v[j]]=dis[u[j]]+w[j];
                flag=0;
            }
        if(flag)
            break;
    }
}
int main()
{
    while(scanf("%d%d",&n,&m),n+m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            scanf("%d%d%d",&a,&b,&t);
            u[i]=a;
            v[i]=b;
            w[i]=t;
        }
        bellman_ford();
        printf("%d\n",dis[n]);
    }
    return 0;
}

 

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