最短路(2) bellman ford和SPFA

2021-08-01 01:11:06 字數 1625 閱讀 5004

首先,如果最短路存在,那麼一定有一條不含環的最短路,因為如果是正環或零環,都可以直接去除,如果有負環,則最短路不存在,所以最短路頂多經過n-1個頂點,那麼我們至多只需要進行n-1次鬆弛操作,每次操作中遍歷所有邊,如果該邊的起點不是inf(已經鬆弛過)那麼就對該邊的終點鬆弛。這樣就一定可以把最短路經過的所有點都鬆弛一遍,即求出了最短路(因為只要可以鬆弛,就一定有更短的方案)。

//bellmanford

#include

#include

#include

#include

using

namespace

std;

const

int maxn = 1000 + 10;

const

int inf = 0x3f3f3f3f;

int u[maxn], v[maxn], w[maxn];

int d[maxn];

int n, m;

int main()

d[1] = 0;

for(int i = 2; i <= n; i++) d[i] = inf;

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

for(int i = 1; i <= 2*m; i++)

if(d[u[i]] < inf) d[v[i]] = min(d[v[i]], d[u[i]] + w[i]);

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

cout

<< d[i] << " ";

return

0;}

思路:

把除起點外的所有點距離設為無限,然後讓起點進入佇列

每次取出佇列的第乙個點,討論他的所有只向點進行鬆弛操作,如果鬆弛成功並且該點並不在佇列中,將該點放入佇列,直到佇列中沒有點為止

和dijkstra的比較

下面是spfa的**

//spfa

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn = 10000 + 10;

const

int inf = 0x3f3f3f3f;

queue

q;int n, m;

int d[maxn];

int vis[maxn];

struct edge

e[maxn];

int head[maxn], cnt;

void add(int u, int v, int w)

int main()

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

d[i] = inf;

q.push(1); vis[1] = 1;

while(!q.empty())}}

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

cout

<< d[i] << " ";

return

0;}

單源最短路徑(2) Bellman Ford 演算法

dijkstra 演算法是處理單源最短路徑的有效演算法,但它對存在負權迴路的圖就會失效。這時候,就需要使用其他的演算法來應對這個問題,bellman ford 中文名 貝爾曼 福特 演算法就是其中乙個。bellman ford 演算法不僅可以求出最短路徑,也可以檢測負權迴路的問題。該演算法由美國數學...

最短路 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演算法 最短路

重要應用 在負權的圖的單源最短路問題 bellman ford 演算法和 dijkstra 演算法都是可以解決單源最短路徑的演算法,乙個實現的很好的 dijkstra 演算法比 bellman ford 演算法的執行時間要低,但dijkstra演算法無法解決存在負權環的圖的單源最短路問題 因為dij...