1. 程式人生 > >Floyd算法

Floyd算法

pat 表示 str names 頂點 while post bsp 最短路

1.算法思想:

定義一個n階方陣序列:A(-1) A(0) A(1) A(2) ....... A(n-1)

A(-1) [i][j]表示頂點Vi到頂點Vj的直接邊的長度,A(-1) 就是鄰接矩陣Edge[n][n]

A(0) [i][j]表示頂點Vi到頂點Vj,中間頂點(如果有,則)是V0的最短路徑長度

A(1) [i][j]表示頂點Vi到頂點Vj,中間頂點序號不大於1的最短路徑長度

A(2) [i][j]表示頂點Vi到頂點Vj,中間頂點序號不大於2的最短路徑長度

A(n-1) [i][j]表示頂點Vi到頂點Vj最短路徑長度

允許帶有負權值的邊,但不能有負權值回路。

2.代碼實現

輸入:

4 8
0 1 1
0 3 4
1 2 9
1 3 2
2 0 3
2 1 5
2 3 8
3 2 6

輸出:

0->1 1 0->1
0->2 9 0->1->3->2
0->3 3 0->1->3
1->0 11 1->3->2->0
1->2 8 1->3->2
1->3 2 1->3
2->0 3 2->0
2->1 4 2->0->1
2->3 6 2->0->1->3
3->0 9 3->2->0
3->1 10 3->2->0->1
3->2 6 3->2

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<map>
 9 #include<set>
10 #include<sstream>
11 using namespace std;
12 typedef long long
ll; 13 const int maxn = 1000 + 10; 14 const int INF = 1 << 25; 15 int T, n, m, cases; 16 int Map[maxn][maxn];//存圖 17 int path[maxn][maxn];//存路徑,path[i][j]表示從頂點vi到vj的最短路徑上頂點j的前一個點的序號 18 int a[maxn][maxn];//存最短路徑長度 19 void Floyd() 20 { 21 for(int i = 0; i < n; i++) 22 { 23 for(int j = 0; j < n; j++) 24 { 25 for(int k = 0; k < n; k++) 26 { 27 a[i][j] = Map[i][j]; 28 if(i != j && a[i][j] < INF)path[i][j] = i;//i到j有路徑 29 else path[i][j] = -1;//從i到j沒有直接的路徑 30 } 31 } 32 } 33 for(int k = 0; k < n; k++) 34 { 35 for(int i = 0; i < n; i++) 36 { 37 for(int j = 0; j < n; j++) 38 { 39 if(k == i || k == j)continue; 40 if(a[i][k] + a[k][j] < a[i][j]) 41 { 42 a[i][j] = a[i][k] + a[k][j]; 43 path[i][j] = path[k][j]; 44 } 45 } 46 } 47 } 48 for(int i = 0; i < n; i++) 49 { 50 for(int j = 0; j < n; j++) 51 { 52 if(i == j)continue; 53 printf("%d->%d\t%d\t", i, j, a[i][j]); 54 stack<int>q; 55 int x = j; 56 while(x != -1) 57 { 58 q.push(x); 59 x = path[i][x]; 60 } 61 cout<<q.top(); 62 q.pop(); 63 while(!q.empty()) 64 { 65 cout<<"->"<<q.top(); 66 q.pop(); 67 } 68 cout<<endl; 69 } 70 } 71 } 72 int main() 73 { 74 cin >> n >> m; 75 for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)Map[i][j] = (i == j ? 0 :INF); 76 int u, v, w; 77 for(int i = 0; i < m; i++) 78 { 79 cin >> u >> v >> w; 80 Map[u][v] = w; 81 } 82 Floyd(); 83 return 0; 84 }

Floyd算法