bellman-ford演算法——最短路問題,判斷是否存在負權迴路或正權迴路
Dijkstra演算法是處理單源最短路徑的有效演算法,但它侷限於邊的權值非負的情況,若圖中出現權值為負的邊,Dijkstra演算法就會失效,求出的最短路徑就可能是錯的。
這時候,就需要使用其他的演算法來求解最短路徑,Bellman-Ford演算法就是其中最常用的一個。該演算法由美國數學家理查德•貝爾曼(Richard Bellman, 動態規劃的提出者)和小萊斯特•福特(Lester Ford)發明。
適用條件&範圍:
單源最短路徑(從源點s到其它所有頂點v);
有向圖&無向圖(無向圖可以看作(u,v),(v,u)同屬於邊集E的有向圖);
邊權可正可負(如有負權迴路輸出錯誤提示
差分約束系統;
Bellman-Ford演算法的流程如下:
給定圖G(V, E)(其中V、E分別為圖G的頂點集與邊集),源點s,陣列Distant[i]記錄從源點s到頂點i的路徑長度,初始化陣列Distant[n]為, Distant[s]為0;
以下操作迴圈執行至多n-1次,n為頂點數:
對於每一條邊e(u, v),如果Distant[u] + w(u, v) < Distant[v],則另Distant[v] = Distant[u]+w(u, v)。w(u, v)為邊e(u,v)的權值;
若上述操作沒有對Distant進行更新,說明最短路徑已經查詢完畢,或者部分點不可達,跳出迴圈。否則執行下次迴圈;
為了檢測圖中是否存在負環路,即權值之和小於0的環路。對於每一條邊e(u, v),如果存在Distant[u] + w(u, v) < Distant[v]的邊,則圖中存在負環路,即是說改圖無法求出單源最短路徑。否則陣列Distant[n]中記錄的就是源點s到各頂點的最短路徑長度。
可知,Bellman-Ford演算法尋找單源最短路徑的時間複雜度為O(V*E).
Bellman-Ford演算法可以大致分為三個部分
第一,初始化所有點。每一個點儲存一個值,表示從原點到達這個點的距離,將原點的值設為0,其它的點的值設為無窮大(表示不可達)。
第二,進行迴圈,迴圈下標為從1到n-1(n等於圖中點的個數)。在迴圈內部,遍歷所有的邊,進行鬆弛計算。
第三,遍歷途中所有的邊(edge(u,v)),判斷是否存在這樣情況:
d(v) > d (u) + w(u,v)
則返回false,表示途中存在從源點可達的權為負的迴路。
之所以需要第三部分的原因,是因為,如果存在從源點可達的權為負的迴路。則 應為無法收斂而導致不能求出最短路徑。
測試程式碼如下:(下面為有向圖的Bellman-Ford演算法。。。。。)
PS:很簡單的演算法,沒什麼特別好說的。自己的程式碼
#include<bits/stdc++.h>
using namespace std;
#define maxn 999
#define inf 0x3f3f3f3f
typedef struct Edge{int form;int to;int w;}edge;
edge ma[maxn];
int dis[maxn];
int k,node,v;
int bellman_ford()
{
for(int i=1;i<=node;i++) //初始化,找正權迴路是初始化為0
dis[i]=inf; //dis代表著從源點到i的距離
dis[v]=0;
for(int i=1;i<=node-1;i++) //歷遍每一個點
{
for(int j=1;j<=k;j++) //歷遍每條邊
{
if(dis[ma[j].form]>dis[ma[j].to]+ma[j].w) //如果v-form的距離大於v-to+to-from的距離就更新v-form的距離
{
dis[ma[j].form]=dis[ma[j].to]+ma[j].w;
}
}
}
int flag=1;
for(int i=1;i<=k;i++) //判斷是否有負權迴路,改變條件後也可以判斷是否有正權迴路
{
if(dis[ma[i].form]>dis[ma[i].to]+ma[i].w)
{
flag=0;
break;
}
}
return flag;
}
int main()
{
scanf("%d %d %d",&node,&k,&v);
for(int i=1;i<=k;i++)
{
scanf("%d%d%d",&ma[i].form,&ma[i].to,&ma[i].w);
}
if(bellman_ford())
{
for(int i=1;i<=node;i++)
{
printf("%d\n",dis[i]);
}
}
else
printf("have negative circle\n");
}
相關推薦
bellman-ford演算法——最短路問題,判斷是否存在負權迴路或正權迴路
Dijkstra演算法是處理單源最短路徑的有效演算法,但它侷限於邊的權值非負的情況,若圖中出現權值為負的邊,Dijkstra演算法就會失效,求出的最短路徑就可能是錯的。 這時候,就需要使用其他的演算法來求解最短路徑,Bellman-Ford演算法就是其中最常用的一個
bellman-ford演算法 最短路
重要應用:在負權的圖的單源最短路問題 Bellman-Ford 演算法和 Dijkstra 演算法都是可以解決單源最短路徑的演算法,一個實現的很好的 Dijkstra 演算法比 Bellman-Ford 演算法的執行時間要低,但dijkstra演算法無法解決存
[ACM] hdu 1217 Arbitrage (bellman_ford最短路,判斷是否有正權迴路或Floyed)
Arbitrage Problem Description Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of a currency in
單源最短路——(Bellman-Ford演算法)超詳細
今天看了一下午的白書的Bellman-Ford演算法,由於能力有限,可能理解不到位。。。。 感覺就是遍歷所有邊更新點,如果有更新的點,繼續遍歷所有邊,直到沒有點更新就退出. #include <iostream> #include <stdio.h> #inc
【最短路】Bellman-ford演算法
今天看啊哈演算法搞懂了Bellman-ford演算法,其實核心程式碼只有四行,還是蠻簡單的,寫了一個板子,程式碼分析容後再議 (我才不是想水部落格呢……) #include <iostream
ACM:最短路,dijkstra,鄰接表的建立,使用鄰接表跟優先佇列的dijkstra,Bellman-Ford,Floyd。。
(一)dijkstra,鄰接矩陣 所有邊權均為正,不管有沒有環,求單個源點出發,到所有節點的最短路。該方法同時適用於有向圖和無向圖。 #include <iostream> #include <string> #include <stack&g
帶有負權值的單源最短路徑-bellman-ford演算法
https://baike.baidu.com/item/Bellman-Ford%E7%AE%97%E6%B3%95/1089090?fr=aladdin&fromid=6039406&fromtitle=bellman-ford 參考百科的c++實現版本 import java.
紫書第十一章-----圖論模型與演算法(最短路徑Dijkstra演算法Bellman-Ford演算法Floyd演算法)
最短路徑演算法一之Dijkstra演算法 演算法描述:在無向圖 G=(V,E) 中,假設每條邊 E[i] 的長度為 w[i],找到由頂點 V0 到其餘各點的最短路徑。 使用條件:單源最短路徑,適用於邊權非負的情況 結合上圖具體搜尋過程,我繪出下表,方便
Bellman-Ford演算法和佇列優化(SPFA)——求單源最短路徑
來源自我的部落格 #include <stdio.h> #include <limits.h> int main(){ int n, m; scanf("%
單源最短路徑之Bellman-Ford演算法
今天介紹一種計算單源最短路徑的演算法Bellman-Ford演算法,對於圖G=(V,E)來說,該演算法的時間複雜度為O(VE),其中V是頂點數,E是邊數。Bellman-Ford演算法適用於任何有向圖,並能報告圖中存在負環路(邊的權重之和為負數的環路,這使得圖中所有經過該環
有權最短路徑問題:貝文曼福德(Bellman Ford)演算法 & Java 實現
一、貝爾曼福德演算法 1. 簡介 貝爾曼福德(Bellman Ford)演算法也是求解單源最短路徑問題,相比狄克斯特拉(dijkstra)演算法,它執行效率會差一些,但是它可以處理邊的權重為負值的情況,而狄克斯特拉演算法要求變的權重不能為負數。 2. 演算法思
最小費用流bellman-ford演算法總結
最小費用流問題是尋找流為F時的最小費用,普通的最大流中邊只有流量限制,而在費用流中還加上了費用,為保證過程可逆和正確性殘餘網路中的負權邊是原邊費用的相反數,求解此類問題的方法依然是貪心,我們在殘餘網路上總是沿著最短路增廣,這樣可以保證在當前流量下,取得最小的費用(權值為費用
Bellman-Ford演算法—求解帶負權邊的最短路徑
1.Dijkstra不能得到含有負權邊圖(這裡就不是環路了)的單源最短路徑 Dijkstra由於是貪心的,每次都找一個距源點最近的點(dmin),然後將該距離定為這個點到源點的最短路徑(d[i]<--dmin);但如果存在負權邊,那就有可能先通過並不是距源點最近的一個
圖論演算法----最短路徑Bellman-Ford演算法詳解
一、題目描述 最短路徑問題 題目描述 平面上有n個點(n<=100),每個點的座標均在-10000~10000之間。其中的一些點之間有連線。若有連線,則表示可從一個點到達另一個點,即兩點間有
練習題 No.22 判斷是否有負圈(Bellman-Ford演算法)
要求 給出一個有向圖,讓你求這個圈裡是否有負權環 限制條件 無 輸入格式 第一行輸入V,E分別代表頂點數和邊數 接下來E行,每行輸入from to cost 代表從from到to的距離為
圖演算法:2、計算帶有負權值的單源最短路徑:Bellman-Ford演算法
原文地址:http://www.wutianqi.com/?p=1912 相關文章: 1.Dijkstra演算法: 2.Floyd演算法: Dijkstra演算法是處理單源最短路徑的有效演算法,但它侷限於邊的權值非負的情況,若圖中出現權值為負的邊,Dijkst
POJ 2253 Frogger ,poj3660Cow Contest(判斷絕對順序)(最短路,floyed)
技術 memset lse 關系 size using onclick second win POJ 2253 Frogger題目意思就是求所有路徑中最大路徑中的最小值。 #include<iostream> #include<cstdio&g
HDOJ 1217 Arbitrage(擬最短路,floyd算法)
same double script strong ram tar per bre center Arbitrage Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/
最短路,dijstra算法
ear 代碼 大於 鏈表 include n) clear esp als #include<iostream> #include<stdio.h> #include<math.h> #include<vector> usi
POJ 3259 Wormholes【最短路/SPFA判斷負環模板】
改變 air ont 數組 算法 他會 HERE push_back init 農夫約翰在探索他的許多農場,發現了一些驚人的蟲洞。蟲洞是很奇特的,因為它是一個單向通道,可讓你進入蟲洞的前達到目的地!他的N(1≤N≤500)個農場被編號為1..N,之間有M(1&l