Bellman-Ford算法图解

一、Bellman-Ford算法用到的“材料”:

1、一个结果数组dis,这个结果数组记录从源点到其他点的最短距离,如dis[10] 表示(加入开始节点标号为1)开始节点1到10号节点的最短距离。

2、C/C++中定义结构体Edge,表示边,内设变量from、to、cost,分别表示这条边的开始标号、终点标号、边长度

3、为了方便测验设置一个边的数组,C++定义:Edge edges[100];

二、Bellman-Ford算法图解

如图所示,针对一般情况分析,对一条边来说,我们想更新数组dis,让dis[i]变成从源点start到编号为index的点的最小值,所以就上图来说,当我们选择一条边e,如果start到e.from的距离可以估计(不是INF),那么start到to节点的距离就可以知道了,如果在之前dis[e.to]已经被更新过了,那么就要判断从start到e.from的距离加上e.cost的值 是否 小于 dis[e.to] 的值,如果小于就更新dis[e.to] = dis[e.from] + e.cost ,如果不是,那么就继续循环或跳出。

三、示例代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#define INF 0x7fffffff
using namespace std;

const int N = 100;
typedef struct Edge{
    int from; 
    int to;
    int cost;
}Edge;

int dis[N];
Edge edges[N];
void init(int n,int st){
    for(int i = 0 ;i <= n; ++i){
        dis[i] = INF ;
    }
    dis[st] = 0 ;
}

void BellmanFord(int n, int m){
    while(true){
        bool update = false;  //如果某一次循环没有更新dis数组,那么就代表这个图遍历完成了。时间复杂度O(V * E)
        
        for(int i = 0 ; i < m; ++i){
            Edge e = edges[i];
            
            if(dis[e.from] != INF && dis[e.from] + e.cost < dis[e.to]){
                dis[e.to] = dis[e.from] + e.cost;
                update = true;
            }
            if(dis[e.to] != INF && dis[e.to] + e.cost < dis[e.from]){
                dis[e.from] = dis[e.to] + e.cost;
                update = true;
            }
        }
        if(!update){
            break;
        }
    }
}
void prt(int n){
    for(int i = 1; i<= n; ++ i){
        printf("%d ",dis[i]);
    }
    cout<<endl;
}
int main(){
    int n , m;    //n个顶点,m条边 
    while(cin>>n>>m){
        init(n , 1);
        for(int i = 0 ; i< m ;++i){
            cin>>edges[i].from>>edges[i].to>>edges[i].cost;
        }
        
        BellmanFord(n , m);
        prt(n);
    }
    return 0;
} 

/*
测试 
7 10
1 2 2 
1 3 5 
2 3 4
3 4 2
2 4 6
2 5 10
5 6 3
4 6 1
6 7 9
5 7 5
*/

 

posted @ 2018-02-11 13:18  砂糖橘子君  阅读(1726)  评论(0编辑  收藏  举报