点击查看代码
#include<cstdio>
#include<algorithm>
using namespace std;
#pragma warning(disable:4996)
const int maxn = 201; //最多不超过200个顶点
const int INF = 0x3fffffff; //表示无穷大
/* Floyd算法,解决全源最短路径问题,即求解图中任意两点u和v的最短路径长度,时间复杂度O(n^3),
因为时间复杂度n^3限制了实际问题顶点数的规模,一般要在200以内,因此使用邻接矩阵存储图。
算法思想:循环n轮,每轮枚举一个顶点k作为中转点,检查是否能使邻接矩阵中的任意两个点i和j的距离更短,
如果能则更新i和j的最短距离dis[i][j],n轮结束后就能得到邻接矩阵中任意两个点i和j的最短距离
*/
int n, m; //顶点数,边数
int dis[maxn][maxn]; //邻接矩阵存储两个点之间的最短距离,如dis[i][j]存储i和j的最短距离
void Floyd() { //以有向图为例。无向图需要增加bool vis[][]数组判断当前边是否访问过,如果访问过则不需要访问,否则重复访问浪费时间
for (int k = 0; k < n; k++) { //循环n轮,每轮枚举一个顶点k作为中转点,检查是否能使邻接矩阵中的任意两个点i和j的距离更短
for (int i = 0; i < n; i++) { //遍历二维矩阵
for (int j = 0; j < n; j++) {
//如果以k为中转点能使i和j的距离更短(注意要判断i和k、k和j是否相连)
if (dis[i][k] != INF && dis[k][j] != INF && dis[i][k] + dis[k][j] < dis[i][j]) {
dis[i][j] = dis[i][k] + dis[k][j]; //如果能,则更新i和j的最短距离dis[i][j]
}
}
}
}
}
int main() {
fill(dis[0], dis[0] + maxn * maxn, INF); //初始化d[maxn][maxn]全部为INF,表示各点之间不相连
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
dis[i][i] = 0; //初始化每个顶点与自己的距离为0
}
int v1, v2, w; //顶点v1、v2、有向边v1->v2的边权
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &v1, &v2, &w);
dis[v1][v2] = w; //存储有向边v1->v2的边权
}
Floyd(); //Floyd()算法求解图中任意两个点之间的最短距离
for (int i = 0; i < n; i++) { //遍历二维矩阵
for (int j = 0; j < n; j++) {
printf("%d ", dis[i][j]); //输出任意两个点之间的最短距离
}
printf("\n"); //每行输出结束要换行
}
return 0;
}