图—单源最短路径算法(一)Bellman-Ford算法

Bellman-Ford算法

这个算法解决的是一般情况下的单源最短路径问题,即可带负权值,但是缺点是效率低。Bellman-Ford算法返回一个布尔值,以表明是否存在一个从源结点可以到达的权重为负值的环路。
它通过对边进行松弛操作来渐进地降低从源结点s到每个结点v的最短路径的估计值v.d,直到该估计值与实际的最短路径权重δ(s,v)相同时为止。

伪代码如下:

BELLMAN-FORD(G,W,s)
    INITALIZE-SINGLE-SOURCE(G,s)
    for i=1 to |G.v|-1
        for each edge(u,v)∈G.E
            RELAX(u,v,w)
    for each edge(u,v)∈G.E
        if v.d>u.d+w(u.v)
            return FALSE
    return TRUE

但是我习惯用《挑战程序设计》中的Bellman-Ford的代码。判断是否存在负圈可另外写一函数。
代码如下:

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 1000;
const int INF = 10000000;
int n,e;
int d[maxn],pre[maxn];
struct edge{
    int from,to,cost;
};
edge es[maxn];
void init(int s)
{
    for(int i=0; i<n; i++)
    {
        d[i] = INF;
        pre[i] = NULL;
    }
    d[s] = 0;
    return;
}

void Bellman_Ford(int s)
{
    init(s);
    while(true)
    {
        bool updata = false;
        for(int i=0; i<e; i++)
        {
            edge e = es[i];
            if(d[e.from]!=INF && d[e.to] > d[e.from] +e.cost)
            {
                d[e.to] = d[e.from] + e.cost;//更新最短路径 
                pre[e.to] = e.from;          //更新父结点 
                updata = true;
            }
        }
        if(!updata) break;
    }
}

int main()
{
    scanf("%d%d",&n,&e);
    int s,t,c;
    for(int i=0; i<e; i++)
    {
        scanf("%d%d%d",&s,&t,&c);
        es[i].from = s;
        es[i].to = t;
        es[i].cost = c;
    }
    Bellman_Ford(0);
    for(int i=0; i<n; i++)
    {
        printf("%d ",d[i]);
    }
    printf("\n");
    for(int i=0; i<n; i++)
    {
        printf("%d ",pre[i]);
    }
    return 0;
}

如果在图中不存在从s可达的负圈,那么最短路不会经过同一个顶点两次
判断是否有负圈

/*判断是否存在负圈*/
bool find_negative_loop()
{
    memset(d,0,sizeof(d));

    for(int i=0; i<n; i++)
    {
        for(int j=0; j<e; j++)
        {
            egde e = es[j];
            if(d[e.to] > d[e.from] + e.cost)
            {
                d[e.to] = d[e.from] + e.cost;
                if(i == V - 1) return true;//如果第n次仍然更新了,则存在负圈
             } 
        }   
    }
    return false;   
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/karry_zzj/article/details/70118337
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞