再论Bellman-Ford算法

前提:了解Bellman-Ford算法

基本模型:

#include<iostream>
using namespace std;

#define inf 0x7fffffff
#define maxx 100
int G[maxx][maxx],dis[maxx];
int n,m;

int min(int a,int b)
{
    return (a>b?b:a);
}

void init(int n)
{
    for(int i=1;i<=n;i++)
    {
        dis[i]=0;
        for(int j=1;j<=n;j++)
            G[i][j]=(i==j?0:inf);
    }
}

void Bellman_Fory()
{
    for(int i=1;i<=n;i++)
        dis[i]=G[1][i];
    dis[1]=0;
    for(int k=2;k<=n;k++)//从dist(1)[i]递推出dist(2)[i],...,dist(n-1)[i]
    {
        for(int i=1;i<=n;i++)//修改每个顶点的dist[i]
        {
            if(i!=1)
                for(int j=1;j<=n;j++)
                {
                    //顶点j到i有直接途径并且途经顶点j可以使得dist[i]缩短
                    if(G[j][i]<inf&&dis[i]>dis[j]+G[j][i])
                        dis[i]=dis[j]+G[j][i];
                }
        }
    }
    /*判断是否存在负权值回路
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(G[i][j]<inf&&dis[j]>dis[i]+G[i][j])
                return false;
        }
        return true;
    }
    */
}

int main()
{
    cin>>n>>m;
    int a,b,c;
    init(n);
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b>>c;
        G[a][b]=c;
    }
    Bellman_Fory();
    for(int i=1;i<=n;i++)
        cout<<dis[i]<<" ";
    cout<<endl;
}

进一步探讨:

用邻接表实现(复杂度是O(n^2))

#include<iostream>
using namespace std;
#define inf 0x7fffffff
#define maxx 1010

typedef struct Edge
{
    int u,v;
    int weight;
}Edge;

Edge edge[maxx];
int dist[maxx];
int n,e,s;//结点数,边数,源点

void init()
{
    cin>>n>>e>>s;
    for(int i=1;i<n;i++)
        dist[i]=inf;
    dist[s]=0;
    for(int i=1;i<=e;i++)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        if(edge[i].u==s)
            dist[edge[i].v]=edge[i].weight;
    }
}

bool Bellman_Ford()
{
    for(int i=1;i<=n-1;i++)
        for(int j=1;j<=n;j++)
            if(edge[j].weight<inf&&dist[edge[j].v]>dist[edge[j].u]+edge[j].weight)
                dist[edge[j].v]=dist[edge[j].u]+edge[j].weight;
    bool flag = 1;
    for(int i=1;i<e;i++)
        if(edge[j].weight<inf&&&&dist[edge[i].v]>dist[edge[i].u]+edge[i].weight)
        {
            flag = 0;
            break;
        }
    return flag;
}

int main()
{
    init();
    if(Bellman_Ford())
    for(int i=1;i<=n;i++)
        cout<<dist[i]<<endl;
    else
        cout<<"No"<<endl;
    return 0;
}

测试样例:

7 10
1 2 6
1 3 5
1 4 5
2 5 -1
3 2 -2
3 5 1
4 3 -2
4 6 -1
5 7 3
6 7 3

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