Floyd也是採用動態規劃的方案來解決在一個有向圖G=(V,E)上每對頂點間的最短路徑問題。運行時間爲Θ(V3)。ios
算法分析:算法
用鄰接矩陣map[][]存儲有向圖,用dist[i][j]表示i到j的最短路徑。設G的頂點爲V={1,2,3...n},對於任意一對頂點i,j屬於V,假設i到j有路徑且中間節點皆屬於集合{1,2,3...k},P是其中的一條最小權值路徑。就是i到j的最短路徑P所經過的中間頂點最大不超過k。spa
設爲從
到
的只以
集合中的節點爲中間節點的最短路徑的長度。code
所以,。blog
for k ← 1 to n do for i ← 1 to n do for j ← 1 to n do if (Di,k + Dk,j < Di,j) then Di,j←Di,k + Dk,j ;
實現代碼:遞歸
/************************************************************************* > File Name: Floyd_Warshall.cpp > Author: He Xingjie > Mail: gxmshxj@163.com > Created Time: 2014年06月12日 星期四 15時57分22秒 > Description: ************************************************************************/ #include<iostream> #include<cstdio> using namespace std; #define MAX 20 #define INF 65535 //map鄰接矩陣,dist記錄最短路徑,path用於最短路徑 int map[MAX][MAX], dist[MAX][MAX], path[MAX][MAX]; int Init() { int n; cin>>n; for (int i=0; i<n; i++) for(int j=0; j<n; j++) { cin>>map[i][j]; dist[i][j] = map[i][j]; path[i][j] = 0; } return n; } void Floyd(int n) { int i, j, k; for (k=0; k<n; k++) for (i=0; i<n; i++) for (j=0; j<n; j++) if (dist[i][k] != INF && dist[k][j] !=INF && dist[i][j] > dist[i][k] + dist[k][j]) { dist[i][j] = dist[i][k] + dist[k][j]; path[i][j] = k; //i到j要通過K節點 } } void PrintShortestPath(int i, int j) { //遞歸打印最短路徑 if (path[i][j] == 0) //表示i->j沒有中間節點 { printf("%d ", j+1); return; } else { PrintShortestPath(i, path[i][j]); PrintShortestPath(path[i][j], j); } } void PrintMap(int n) { int i, j; for (i=0; i<n; i++) { for (j=0; j<n; j++) cout<<dist[i][j]<<" "; cout<<endl; } cout<<endl; } int main() { int n; freopen("input.txt", "r", stdin); n = Init(); Floyd(n); PrintMap(n); for (int i=0; i<n; i++) { for (int j=0; j<n; j++) { if (i != j) { cout<<i+1<<" "; PrintShortestPath(i, j); cout<<endl; } } cout<<endl; } return 0; } 2014/6/13 23:24
輸入數據:ip
5 0 3 8 65535 -4 655535 0 65535 1 7 65535 4 0 65535 65535 2 65535 -5 0 65535 65535 65535 65535 6 0
輸出數據:ci
參考:get
http://zh.wikipedia.org/zh/%E5%BC%97%E6%B4%9B%E4%BC%8A%E5%BE%B7%E7%AE%97%E6%B3%95input