首先,如果最短路存在,那麼一定有一條不含環的最短路,因為如果是正環或零環,都可以直接去除,如果有負環,則最短路不存在,所以最短路頂多經過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...