边上权值为任意值的单源最短路径问题——Bellman--Ford算法

Dijkstra算法的局限性:不能处理权值为负值的情形,Dijkstra算法在利用顶点u的dist[ ]值递推各顶点的dist[ ]值时,前提是顶点u的dist[ ]值是当前最短路径长度最小的,如果图中所有边的权值都是正的,这样推导没有问题,但如果有负权值的边,这样推导就不正确。


Bellman-Ford算法思想:从源点逐次途经其他顶点,以缩短到达终点的最短路径 长度。

限制条件:要求图中不能包含权值总和为负值的回路。

例题:求顶点0到其他各顶点的最短路径长度,并输出对应的最短路径

《边上权值为任意值的单源最短路径问题——Bellman--Ford算法》

#include <cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxint 0x3f3f3f3f
void Bellman(int v0);
int map[110][110];
int dist[110];
int path[110];
int n;
int main()
{
    int u,v,w;
    scanf("%d",&n);
    memset(map,maxint,sizeof(map));
    while(1)
    {
        scanf("%d%d%d",&u,&v,&w);
        if(u==-1&&v==-1&&w==-1) break;
        map[u][v]=w;
    }
    for(int i=0;i<n;i++)///如果i==j,map[i][j]=0;
        for(int j=0;j<n;j++)
        if(i==j)
        map[i][j]=0;
    Bellman(0);
    int shortest[110];
    for(int i=1;i<n;i++)
    {
        printf("%d\t",dist[i]);
        memset(shortest,0,sizeof(shortest));
        int k=0;
        shortest[k]=i;
        while(path[shortest[k]]!=0)
        {
            k++;
            shortest[k]=path[shortest[k-1]];
        }
        k++;
        shortest[k]=0;
        for(int i=k;i>0;i--)
            printf("%d-",shortest[i]);
        printf("%d\n",shortest[0]);
    }
}
void Bellman(int v0)
{
    for(int i=0;i<n;i++)
    {
        dist[i]=map[v0][i];
        if(i!=v0&&dist[i]<maxint)
            path[i]=v0;
        else
            path[i]=-1;
    }

    for(int k=2;k<n;k++)///k表示:从源点v0出发最多不经过k条边到达终点u
         for(int u=0;u<n;u++) ///u表示终点,修改每个顶点的dist[u]和path[u]
        if(u!=v0)
    {
        for(int j=0;j<n;j++)///考虑其他每个顶点
            if(map[j][u]<maxint&&dist[j]+map[j][u]<dist[u])
        {
            dist[u]=dist[j]+map[j][u];
            path[u]=j;
        }
    }
}

《边上权值为任意值的单源最短路径问题——Bellman--Ford算法》

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