Floyd算法,全源最短路径

点击查看代码
#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;
}

posted @ 2022-09-30 22:49  zhaoo_o  阅读(4)  评论(0编辑  收藏  举报