所有節點對之間的最短路問題(All Pair Shortest Path)--《演算法導論》
給定一個有向圖求出裡面所有節點對之間的最短路徑。
問題的詳細描述見Wikipedia:https://en.wikipedia.org/wiki/Shortest_path_problem。
介紹兩個演算法
Floyd
這是一個動態規劃演算法。設
dkij={wijmin{dk−1ij,dk−1ik+dk−1ij}x=0x!=0
虛擬碼
for k=1 to|V|
fori=1 toV
forj=1 toV
d[i][j]=min{d[i][j],d[i][k]+d[k][j]}
c++程式碼
void floyd(int n)
{
memcpy(d,w,sizeof(w));//初始化d(0)
for(int k=1 ; k<=n ; ++k)
for(int i= 1 ; i<=n ; ++i)
for(int j=1 ; j<=n ; ++j)
d[i][j] = min(d[i][j],d[i][k]+d[k][j]);
}
Johnson(用於稀疏圖)
Johnson演算法的核心思想是直接對每個頂點做一次Dijkstra,這樣時間複雜度只有
重塑權重值
設
1、
w(p)=δ(v0,vk)⇔w′(p)=δ(v0,vk)
2、w(p) 不包含負環⇔w′(p) 不包含負環
下面證明取權重對映
w′(p)=∑ni=1w′(vi,vi−1)
=∑ni=1w(vi,vi−1)+h(v0)−h(vk)
=w(p)+h(v0)−h(vk)
第一條肯定滿足了,因為