單源最短路問題,就是對乙個邊帶權圖g和其上一點s,求g上每一點到s的權最小路
性質: 1.最短路上不會有環
2.將達不到或者暫時達不到的點的距離習慣記做無窮
3.該問題滿足最優子結構,即最短路的子圖也為最短路
如何記錄:對每個節點v,維護乙個值v.pi,表示這個點的前驅節點。求解完成之後使用他構造最短路徑樹即可、
基本操作:
最短路徑估計:對每個點維護乙個值v.d,為當前估計的s到他的距離
初始化:將所有v.d置為無窮,v.pi置為null
鬆弛:對點u,v,若我們已經求出了u的最短路,且u,v鄰接,對比u.d+w(u+v)和v.d,若v.d比較大,說明從u到達v比v當前認為的最短路更近,就可以將v.d置為u.d+w(u+v),將v.pi置為u
之後的演算法就基於鬆弛操作進行
bellmanford演算法
能夠解決帶負權圖的最短路問題,若圖上有負權迴路,返回false表示無解
這個演算法的思路比較暴力:每次把每條邊鬆弛一次,重複v-1次。每次鬆弛完所有邊後可以保證滿足最短路性質的點距離原點的深度多了一層,所以重複v-1次後可以保證最短路已完成。
對於負權迴路的判斷:完成上面步驟後遍歷一遍每條邊,若還可以鬆弛,則說明有負權迴路。
優化:如果某次操作中沒有鬆弛,則說明之後也不會再鬆弛了,在這停止。
以hdu2544為例
//其實這題並沒有用到bellmanford判負值的操作
#include using namespace std;
const int maxn=20000;
int vpi[200],vd[200],v,e;//前驅節點,最大值估計
struct edg
ed[maxn];
void init()
}bool bellmanford()
}if(flag)break;
}for(int i=1;i<=e;i++)
return true;
}int main()
{ while(cin>>v>>e,v!=0)
{e*=2;
init();
bellmanford();
cout<
單源最短路
題目描述 給出乙個有向圖,請輸出從某一點出發到所有點的最短路徑長度。輸入第一行包含三個整數n m s,分別表示點的個數 有向邊的個數 出發點的編號。接下來m行每行包含三個整數fi gi wi,分別表示第i條有向邊的出發點 目標點和長度。輸出n行,每行n個用空格分隔的整數,其中第i個整數表示從點s出發...
單源最短路
恢復內容開始 dijkstra spfa floyd多源變單源 熱浪 模板題 使用spfa過 spfa 從佇列中取出點進行鬆弛操作 使用st記錄點是否還在佇列中 如果這個點本來就存在佇列中那麼就重複加入點了void spfa int s 信使 廣播式求時間 求廣播所有點的最短時間 每個點接受到向他的...
多源最短路和單源最短路
多源最短路 例題 usaco08open clear and present danger s 單源最短路例題 dijkstra求最短路 i 給定乙個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出 1。輸入格式 第...