传送门:
Floyd
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
递推式a[i][j] = min(a[i][j], a[i][k] + a[k][j])
如果只是判断连通性,可改成a[i][j] |= a[i][k] & a[k][j];
此处存路径是按照倒叙存储路径path[i][j]表示从顶点vi到vj的最短路径上顶点j的前一个点的序号,这里有正序存路径使得字典序最小,而且这里必须在初始化的时候初始化path,如果有边就要初始化。
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 }
来源:https://www.cnblogs.com/fzl194/p/8729340.html