可以簡單的通過執行|v|次單源最短路徑演算法來解決,每次使用乙個不同的結點作為源結點
多數演算法採用鄰接矩陣來表示圖,因此
演算法的輸入為乙個n*n的矩陣w,代表乙個有n個結點的有向圖g = (v, e)的邊的權重
wij = 0 若i = j
權重 若i != j,且(i, j)屬於e
inf 若i != j,且(i, j)不屬於e
輸出也是乙個n *n的矩陣d = (dij),dij表示從結點i到結點j的一條最短路徑的權重
以及乙個前驅結點矩陣p = (pij),pij在i = j或者從i到j不存在路徑時為nil,在其他情況下給出從結點i到結點j的某條最短路徑上結點j的前驅結點
矩陣的一行第i行所誘導的子圖,應當是一棵根節點為i的最短路徑樹,最短路徑的輸出
print-all-pairs-shortest-path(p)
for i = 1 to n
for j = i+1 to n
print-pairs-shortest-paht(p, i, j)
print-pairs-shortest-paht(p, i, j)
if(i == j)
print i
//遞迴輸出的終止條件
if(pij == nil)
print "no path from "i" to "j" exists
else
print-pairs-shortest-paht(p, i, pij)
print j
floyd-warshall演算法(動態規劃)
最短路徑的結構
一條路徑p = 上的中間結點指除了v1和vn之外的任意結點,也就是處於集合中的結點
圖g所有結點v = ,考慮其中乙個子集;
對任意結點對i, j屬於v,考慮結點i到結點j的所有中間結點均取自集合的路徑,並且設p為其中權重最小的路徑
dij(k)表示該最短路徑的權重
1) k不是路徑p上的中間結點,則路徑p上的所有中間結點都屬於集合;從而dij(k) = dij(k-1)
2) k是路徑p上的中間結點,則路徑p可以分解為i——>k——>j【p1和p2】,由於k不是p1或者p2上的中間結點,因為k是端點,從而dij(k) = dik(k-1) + dkj(k-1)
所有結點對最短路徑問題的乙個遞迴解
dij(k) = wij 若k = 0
min(dij(k-1), dik(k-1) + dkj(k-1) 若k >= 1
自底向上計算最短路徑問題
floyd-warshall(w)
n = w.rows
d(0) = w
for k = 1 to n
let d(k) be a new n * n matrix
for i = 1 to n
for j = 1 to n
dij(k) = min(dij(k-1), dik(k-1)+dkj(k-1))
return d(n)
時間複雜度為o(n^3)
構建一條最短路徑
在計算d的同時計算前驅矩陣p
初始化:
pij(0) = nil 若i = j 或 wij = inf
i 若i != j 且 wij < inf
迭代更新:
pij(k) = pij(k-1) 若
dij(k-1) <= dik(k-1)+dkj(k-1)
pkj(k-1) 若
dij(k-1) > dik(k-1)+dkj(k-1)
然後再根據一開始的輸出演算法進行輸出即可
johnson演算法(適用於稀疏圖,輸入為鄰接鍊錶)
如果圖g = (v, e)中所有的邊權重w皆為非負值,可以對每個結點執行一次dijkstra演算法來找到所有結點對之間的最短路徑
如果圖g = (v, e)中存在權重w為負的邊,需要通過一種技術——
重新賦予權重
來將權重轉換為正的,再採用dijkstra演算法
新賦予的權重必須滿足兩個提交
1) 不改變最短路徑
2) 所有的邊(u, v),新權重為非負值
具體做法,引入新結點s,對圖g中每個結點v,定義h(v) = t(s, v),即s到v的最短路徑長度
w'(u, v) = w(u, v) + h(u) - h(v)即可
多源對多源最短路徑
魔方國有n座城市,編號為1 sim n1 n。城市之間通過n 1條無向道路連線,形成乙個樹形結構。在若干年之後,其中p座城市發展成了大都會,道路的數量也增加到了m條。大都會之間經常有 往來,因此,對於每座大都會,請你求出它到離它最近的其它大都會的距離。蒟蒻第一次見多源對多源最短路,沒想到是這種處理方...
多源最短路徑問題
problem description tonyy是乙個喜歡到處浪的男人,他的夢想是帶著蘭蘭姐姐浪遍 的各個角落,不過在此之前,他需要做好規劃。現在他的手上有乙份 地圖,上面有n個城市,m條交通路徑,每條交通路徑都是單行道。他已經預先規劃好了一些點作為旅遊的起點和終點,他想選擇其中乙個起點和乙個終點...
多源最短路徑問題 floyd warshall
儲存圖如下 的演算法思想 該段 的基本思想是 最開始只允許1號頂點進行中轉,接下來只允許經過1號和2號頂點進行中轉.允許經過1 n號所有頂點進行中轉,求任意兩個點之間的最短距離用一句話概括,就是從i號頂點到j號頂點只經過前k號點的最短路徑 floyd warshall核心演算法 5行 for k 1...