Floyd Algorithm
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXV = 510; // 最大顶点数
const int INF = 1000000000; // 无穷大
//顶点数,边数,邻接矩阵
int V, E, G[MAXV][MAXV];
//A用来记录当前已经求得的任意两个顶点最短路径长度
//Path用来记录当前两顶点间最短路径要经过的中间顶点
int A[MAXV][MAXV], Path[MAXV][MAXV];
void Floyd(){
int i, j, k;
// 这个双循环对数组A[][]和Path[]进行了初始化
for(i = 0; i < V; ++i){
for(j = 0; j < V; ++j){
A[i][j] = G[i][j];
A[i][i] = 0; // 对角线元素都为 0
Path[i][j] = -1;
}
}
// 下面这个三层循环是本算法的主要操作,完成了以k为中间点对所有顶点对{i,j}进行检测和修改
for(k = 0; k < V; ++k){
for(i = 0; i < V; ++i){
for(j = 0; j < V; ++j){
if(A[i][j] > A[i][k] + A[k][j] ){
A[i][j] = A[i][k] + A[k][j];
Path[i][j] = k;
}
}
}
}
}
//打印最短路径,采用递归
void PrintPath(int u, int v){
if(Path[u][v] == -1)
printf("%d ", v); // 直接输出
else{
int mid = Path[u][v];
PrintPath(u, mid); // 处理 mid 前半段路径
PrintPath(mid, v); // 处理 mid 后半段路径
}
}
int main(){
int a, b;
scanf("%d %d", &V, &E);
fill(G[0], G[0] + MAXV * MAXV, INF); // 初始化图
for(int i = 0; i < E; i++){
scanf("%d %d", &a, &b);
scanf("%d", &G[a][b]); // 读入边权
}
// 查询 st -> end 的最短路径
int st, end; // 起点,终点
scanf("%d %d", &st, &end);
Floyd(); // Floyd算法入口
// 打印Floyd算法处理后的Path[][], A[][]数组
printf("Path\n");
for(int i = 0; i < V; i++){
for(int j = 0; j < V; j++)
printf("%4d", Path[i][j]);
printf("\n");
}
printf("A\n");
for(int i = 0; i < V; i++){
for(int j = 0; j < V; j++){
if(A[i][j] == INF){
printf(" ∞");
continue;
}
printf("%4d", A[i][j]);
}
printf("\n");
}
// 输出查询结果
printf("从%d到%d的路径:%d ", st, end, st);
PrintPath(st, end);
return 0;
}
sample input1:
7 12
0 1 4
0 2 6
0 3 6
1 4 7
1 2 1
3 2 2
3 5 5
2 4 6
2 5 4
5 4 1
4 6 6
5 6 8
0 6
sample output1:
Path
-1 -1 1 -1 5 2 5
-1 -1 -1 -1 5 2 5
-1 -1 -1 -1 5 -1 5
-1 -1 -1 -1 5 -1 5
-1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 4
-1 -1 -1 -1 -1 -1 -1
A
0 4 5 6 10 9 16
∞ 0 1 ∞ 6 5 12
∞ ∞ 0 ∞ 5 4 11
∞ ∞ 2 0 6 5 12
∞ ∞ ∞ ∞ 0 ∞ 6
∞ ∞ ∞ ∞ 1 0 7
∞ ∞ ∞ ∞ ∞ ∞ 0
从0到6的路径:0 1 2 5 4 6
sample input2:
4 8
0 3 7
0 1 5
1 2 4
1 3 2
2 0 3
2 1 3
2 3 2
3 2 1
1 0
sample output2:
Path
-1 -1 3 -1
3 -1 3 -1
-1 -1 -1 -1
2 2 -1 -1
A
0 5 8 7
6 0 3 2
3 3 0 2
4 4 1 0
从1到0的路径:1 3 2 0