任意兩點之間的最短路徑問題(Floyd-Warshall演算法)
阿新 • • 發佈:2019-01-08
求解所有兩點之間的最短路問題叫做任意兩點之間的最短路問題。Floyd-Warshall演算法考慮的是 一條最短路徑上的中間結點。例如,簡單路徑p={v1,v2,...vl}上的中間結點指的是路徑p上除了v1和 vl之外的任意節點,也就是處於集合{v2,v3,...vl-1}中的節點。 Floyd-Warshall演算法基於以下: 假定圖G的所有頂點為V={1,2,3,...,n},考慮其中的一個子集{1,2,..,k},這裡的K是小於n的整數。 對於任意的節點i,j屬於V,從i到j的所有中間結點都取自於集合{1,2,3,...,k}的路徑,並設p為其中權重最小的路徑,也就是說路徑p是簡單路徑。Floyd-Warshall演算法利用了路徑p和從i到j之間中間結點 取自集合{1,3,..,k-1}的最短路徑之間的關係。該關係依賴於結點k是否是路徑p上的一箇中間節點。 (1)如果結點k不是路徑p上的中間結點,則路徑p上的所有中間結點都屬於集合{1,2,...,k-1}.所以,從結點i到結點j的中間結點取自於結合{1,2,...,k}的一條最短路徑。 (2)如果結點k是路徑p上的中間結點,則路徑p可以分解為i~k,k~j。 通過以上分析,可以得出以下結論: 記i到j的最短路徑為d[i][j],那麼具有以下遞推公式: d[i][j]= d[i][j] 最短路徑不通過k = min(d[i][j],d[i][k]+d[k][j]) 最短路徑通過k可以不斷的使用同一個公式進行更新 min(d[i][j],d[i][k]+d[k][j]) 以上演算法使用DP策略,可以在O(|V|3)時間裡求得所有兩個結點之間的最短路徑。
int d[MAX_V][MAX_V]; //d[u][v]表示邊e=(u,v)的權值(不存在設為INF,d[i][i]=0)
int V; //頂點數目
void floyd_warshall(){
for(int k=0;k<V;k++){
for(int i=0;i<V;i++){
for(int j=0;j<V:j++){
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
}
}
}