Bellman-Ford算法圖解
阿新 • • 發佈:2018-02-11
def typedef image img pda string start 針對 我們
一、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 */
Bellman-Ford算法圖解