该算法为多源点最短路径算法,可以找出任意两个节点之间的最短路径以及最短距离,但是代价也是巨大的,时间复杂度为O(n^3),核心是三重for循环,第一重指的是中转节点,第二重指的是起始节点,第三重是终止节点,图由邻接矩阵的形式存储。外加一个存储当前最短路的下一个节点的矩阵的数据结构,由该矩阵,可以找出最短路径,以及存储一个最短路径距离的矩阵,可直接找出最短路径距离。
/*
7
0 12 1000 1000 1000 16 14
12 0 10 1000 1000 7 1000
1000 10 0 3 5 6 1000
1000 1000 3 0 4 1000 1000
1000 1000 5 4 0 2 8
16 7 6 1000 2 0 9
14 1000 1000 1000 8 9 0
author:wx time:2022.2.27
*/
#include <iostream>
using namespace std;
const int N = 1e3 + 10;
int d[N][N]; // 保存最短距离
int p[N][N]; // 保存最短路径上的下一个节点
int n;
int mp[N][N]; // 邻接矩阵
int start, end;
void input() {
cout << "请输入顶点数:\n";
cin >> n;
cout << "请输入邻接矩阵:\n";
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> mp[i][j];
}
}
}
void init() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
d[i][j] = mp[i][j];
p[i][j] = j; // 这一步初始化很重要 i表示起点,j表示终点
}
}
}
void floyd() {
init();
for (int k = 0; k < n; k++) { // 中转点
for (int i = 0; i < n; i++) { // 起点
for (int j = 0; j < n; j++) { // 终点
if (k == i || k == j) continue; // 当中转点和起点或者终点重合时,跳过
if (d[i][k] + d[k][j] < d[i][j]) {
d[i][j] = d[i][k] + d[k][j];
p[i][j] = p[i][k]; // 这一步也很重要
}
}
}
}
}
void output() {
cout << "请输入起点和终点编号(从0开始编号):\n";
cin >> start >> end;
cout << "最短距离为:" << d[start][end] << endl;
cout << "最短路径为:\n";
cout << start << "->";
int k = p[start][end];
while (k != end) {
cout << k << "->";
k = p[k][end];
}
cout << end;
}
int main() {
input();
floyd();
output();
return 0;
}