單源最短路徑問題,給定乙個圖g=(v,e),找出從給定的源點s∈v到其它每個結點v∈v的最短路徑。在開始各種單源最短路徑之前,都需要預先對節點進行初始化,對於每個節點這裡主要記錄了三種演算法:dijkstra: 貪心, floyd: 動歸 (spfa:它沒了)
p3371 【模板】單源最短路徑(弱化版) : ford無法通過,spfa和dijkstra可通過
p4779 【模板】單源最短路徑(標準版):只有dijkstra可通過
v
,維持乙個屬性v.d
,記錄從源節點s
到節點v
的最短路徑長度,v.π
記錄其前驅節點
所有的單源最短路徑演算法都需要使用到鬆弛操作
鬆弛操作是對於一條從節點u
到節點v
的權重為w
的一條邊,將從結點s
到結點u
之間最短路徑加上結點u
到v
之間的邊的權重,然後與當前的s
到v
的最短路徑估計v.d
進行比較,看有沒有變小。如果變小,則對v.d
和v.π
進行更新,這一操作就稱為「鬆弛」
可以有負權重的邊,但不能有負權重的環因為總共只有
|v|
個節點,且不存在負權重的環,所以從s
出發,通過|v| - 1
步一定能到達所有能到達節點,並且通過不斷的鬆弛操作,就能或得從s
出發的所有最短路徑了。演算法複雜度就是o(v
e)o(ve)
o(ve)
舉個栗子
**部分:
#include
#include
using
namespace std;
#define n 110
#define m 5100
int edge[m][3
], ans[n]
;// 儲存邊
intmain()
for(
int i =
0; i < n -
1; i++)}
// 輸出結果
for(
int i =
1; i <= n; i++
)return0;
}
spfa(shortest path faster algorithm)演算法是求單源最短路徑的一種演算法,它是bellman-ford的佇列優化,演算法複雜度為o(k
e)o(ke)
o(ke
), k是乙個常數,指每個點平均進隊次數(在稀疏圖中k較小,在稠密圖中k較大),因此演算法穩定性較差。
實現過程:
存入圖,一般使用鏈式前向星
建立乙個佇列,將起始節點放入佇列
每次從佇列中取出乙個節點x
,遍歷所有和x
相鄰的節點y
,然後進行鬆弛操作,如果能進行鬆弛操作,則將節點y
也加入到佇列中(如果已在佇列中則不需要重複加入),這個期間中可以記錄節點鬆弛的次數,如果鬆弛次數大於n-1次,就說明圖中有負環。
**部分:
#include
#include
#include
using
namespace std;
#define n 110
#define m 5100
struct edge // 邊
arr[m]
;int head[n]
, length =
1, ans[n]
;void
add(
int u,
int v,
int w)
void
spfa
(int n,
int m,
int s)}}
}}intmain()
spfa
(n, m, s)
;for
(int i =
1; i <= n; i++
)return0;
}
該演算法要求所有邊的權重均為非負值!
模擬一下這個過程:
**部分:
#include
#include
#include
#include
using
namespace std;
#define n 1100
#define m 2100
struct edge
arr[m]
;int head[n]
, length =
1, ans[n]
;bool vis[n]
;void
add(
int u,
int v,
int w)
void
dijkstra
(int n,
int m,
int s)}}
}int
main()
dijkstra
(n, m, s)
;for
(int i =
1; i <= n; i++
)return0;
}
單源最短路徑
include define max 999 define maxverts 10 typedef struct graph void chushi graph g void dij graph int key,int int int main for i 1 i g.numverts i dij ...
單源最短路徑
最優子結構 最短路徑的子路徑也是最短路徑,動態規劃和貪心演算法的乙個重要指標。環路 一條最短路徑不可能包含環路 1 環路權重為負,如果有一條環路權重為負,則不存在最短路徑 2 環路權重為零,如果包含該環路,則將該環路去掉即可 3 環路權重為正,去掉改環路可以得到更短的路徑,因此不可能是最短路徑 最短...
單源最短路徑
單源最短路徑問題,即在圖中求出給定頂點到其他任一頂點的最短路徑。1.最短路徑的最優子結構性質 該性質描述為 如果p i,j 是從頂點i到j的最短路徑,k和s是這條路徑上的乙個中間頂點,那麼p k,s 必定是從k到s的最短路徑。證明 假設p i,j 是從頂點i到j的最短路徑,則有p i,j p i,k...