bellman ford演算法 最短路

2021-07-30 14:57:30 字數 2300 閱讀 7950

重要應用:在負權的圖的單源最短路問題

bellman-ford 演算法和 dijkstra 演算法都是可以解決單源最短路徑的演算法,乙個實現的很好的 dijkstra 演算法比 bellman-ford 演算法的執行時間要低,但dijkstra演算法無法解決存在負權環的圖的單源最短路問題(因為dijkstra演算法每迴圈一次,確定一條到某個頂點的最短路,之所以能確定,是因為每條邊都是正值,若到達其他頂點的最短路經過該頂點,則最短路總權值會更大)。

bellman-ford 演算法描述:

如求下圖單源最短路徑,以1為源點,求到各頂點的最短路徑,黑色代表權值,紅色代表第幾條邊(是第幾條邊在實際中會不同,這裡是假設 )

1.初始化:

將除源點外的所有頂點的最短距離估計值 d[v] =+∞,源頂點距離為 0;

2.迭代求解計算最短路徑:

執行 v - 1 次 (遍歷一條最短路徑經過的點最多是v-1個嘛,所有鬆弛|v|-1次後最短路必然會出現!);

反覆對邊集e中的每條邊進行鬆弛操作,(即如果起點 u 的距離 d 加上邊的權值 w 小於終點 v 的距離 d,則更新終點 v 的距離值 d),使得頂點集v中的每個頂點v的最短距離估計值逐步逼近其最短距離;

第一次迴圈:

從第一條邊開始到第十條邊進行鬆弛操作;

得到下圖:

第二次迴圈:

也是從第一條邊開始到第十條邊進行鬆弛操作;與上面同理;

得到如圖;

第三次迴圈:

也是從第一條邊開始到第十條邊進行鬆弛操作;與上面同理;

因為第三次迴圈發現任何沒有任何乙個更新,說明到各個頂點的最短路都已經找到,break;跳出迴圈,結束

3.檢驗負權迴路:

遍歷圖中的所有邊,計算 u 至 v 的距離,如果對於 v 存在更小的距離,則說明存在環(因為經過上面步驟二, 如果不存在負環,則到各點的最短路已經確定);

for(i=1;i<=enum;i++) //檢查有無負權環  

}

**:無路徑

#include

#include

#define max 99999

int m,n,d[10000];//n條邊

struct edgee[10000];

bellmenford(int root)

d[root]=0;

for(k=0;k1;k++)} }

for(i=1;i<=n;i++)

}for(i=1;i<=m;i++)

}int main()

bellmenford(1);

return

0;}

有路徑輸出:

#include

#include

#define max 99999

int m,n,d[10000],pre[10000];//n條邊,d表示到某頂點的總權值,pre記錄路徑

struct edgee[10000];

bellmenford(int root)

d[root]=0;

for(k=0;k1;k++)} }

for(i=1;i<=n;i++)

}for(i=1;i<=m;i++)

if(i!=root)printf("%d",root);

printf("\n");

}}int main()

bellmenford(1);

return

0;}

最短路 Bellman Ford演算法

建立兩個結構體 struct shuzhu 中,u.d存放的是到源節點的當前最短距離,u.f存放的是到節點v的當前最短路徑的前乙個節點 struct node 中,flag 表示的是該節點 的標號,w表示的是邊 u到v的權重。核心 鬆弛距離 if v.d u.d w 在 中就是 if a q fla...

最短路問題(Bellman Ford演算法)

思路 選取乙個頂點v作為起點,用陣列d i 表示到該頂點到i頂點的最短路徑,那麼該點的最短路徑的d v 0為0.然後從改點出發更新該點附近的最短路徑,需要注意的是,每次更新完的d i 值並不一定就是最短路徑,因為可能存在其他路徑更短,例如從b到e的最短路徑為a c d f e,d 4 11。但是從b...

最短路之bellman ford演算法

先來說下bellman ford演算法的基本思想。假設在乙個有向圖中有n個點,那麼從源點到任意其他一點的最短路徑數量肯定不超過n 1 假設不含迴路 那樣放鬆一下限制的話,對於任意一條路徑來說,將n 1條邊都嘗試著 鬆弛 一下,那樣的話,肯定就可以將這條路徑變為最短路。對於bellman ford演算...