Bellman ford 演算法詳解

2022-05-19 02:45:11 字數 2129 閱讀 6767

昨天說的dijkstra固然很好用,但是卻解決不了負權邊,想要解決這個問題,就要用到bellman-ford.

我個人認為bellman-ford比dijkstra要好理解一些,還是先上資料(有向圖):

5 712

8135

23 -6

5 4 -324

735 -2

45 -3

在講述開,先設幾個陣列:

origin[i]表示編號為i這條邊的起點編號,如origin[4]=2

destination[i]表示編號為i這條邊的終點編號,如origin[5]=5

value[i]表示編號為i這條邊的權值,如value[3]=-6

dis[i],和昨天一樣,源點到i號點的估計距離,經過不斷更新會變成時機距離,就是答案。

bellmanford的實際意義就是掃瞄一條邊,看如果走這條邊能不能使這條邊的dis[destination[i]],變少,現在我來模擬一下:

初始的dis:[0,∞,∞,∞,∞]

首先從第一條邊1 2 8開始,判斷走這條邊能不能使這條邊的終點的dis變短,原本dis[2]=∞,而dis[1]=0,而這條邊的權值:value[1]=8,0+8<∞所以將dis[2]更新成8.

dis[0,8,∞,∞,∞]

然後是第二條邊,用剛才的方法將dis[3]從∞更新成5.

dis[0,8,5,∞,∞]

第三條2 3 -8,原本的dis[3]=5,如果走第三條邊,則dis[3]=dis[2]+value[3]=8+(-6)=2<5,所以dis[3]更新成2.

dis[0,8,2,∞,∞]

以此類推,經過第一輪更新,dis陣列如下:

dis[0,8,2,15,0]

但是第一次更新後,並不是最優解於是開始第二次更新。

按照第一次更新的步驟一步一步來得到的答案是

dis[0,8,2,-3,0]

這便是最優解,但是問題來了,一般要更新多少次呢?

n-1次。這樣能保證更新出的一定是最優解。

好了,呈上**:

#include #include 

#include

#include

#include

#include

using

namespace

std;

int dis[10010

];int origin[10010],destination[10010],value[10010

];//剛剛說過的三個陣列

intn,m;

void bellman_ford(inta)

intmain()

有些人可能發現了,很多時候實際上不用更新n-1次,因此我們可以用佇列優化:

每次選出隊首點,對與隊首點鏈結的所有點的dis進行更新,並加入佇列,然後隊首點pop出佇列,

這個演算法最好用鄰接表實現,**如下:

#include #include 

#include

#include

#include

#include

#include

using

namespace

std;

int dis[10010

];int book[10010

];int origin[10010],destination[10010],value[10010

];int

n,m;

inttotal;

int next[10010],head[10010

];void adl(int a,int b,int c)//

鄰接表void bellman_ford(int

a) }

}q.pop();

//彈出隊首元素

} }

intmain()

bellman_ford(1);

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

cout

<"";

}

總結一下,bellman_ford的空間複雜度是m時間複雜度是o(nm),經過佇列優化,時間複雜度是<=o(nm)。

Bellman ford 演算法詳解

昨天說的dijkstra固然很好用,但是卻解決不了負權邊,想要解決這個問題,就要用到bellman ford.我個人認為bellman ford比dijkstra要好理解一些,還是先上資料 有向圖 5 712 8135 23 6 5 4 324 735 2 45 3 在講述開,先設幾個陣列 orig...

Bellman Ford演算法,SPFA演算法

bellman ford 演算法能在更普遍的情況下 存在負權邊 解決單源點最短路徑問題。對於給定的帶權 有向或無向 圖g v,e 其源點為 s,加權函式w是 邊集e 的對映。對圖g執行 bellman ford 演算法的結果是乙個布林值,表明圖中是否存在著乙個從源點s 可達的負權迴路。若不存在這樣的...

Bellman Ford演算法 模板

如題,給出乙個有向圖,請輸出從某一點出發到所有點的最短路徑長度。輸入格式 第一行包含三個整數n m s,分別表示點的個數 有向邊的個數 出發點的編號。接下來m行每行包含三個整數fi gi wi,分別表示第i條有向邊的出發點 目標點和長度。輸出格式 一行,包含n個用空格分隔的整數,其中第i個整數表示從...