简介
Floyd算法是一种用于求解加权图中任意两点之间的最短路径的算法。它是一种动态规划算法,通过不断迭代更新最短路径矩阵来求解所有最短路径。
特点
Floyd算法具有以下特点:
- Floyd算法可以求解所有顶点之间的最短路径,而不仅仅是单源最短路径。
- Floyd算法的时间复杂度为 O(n^3),其中 n 是图中顶点的个数。
- Floyd算法的空间复杂度为 O(n^2)。
应用
Floyd算法在计算机科学中有着广泛的应用,包括:
- 路由规划: Floyd算法可以用于计算网络中任意两点之间的最短路径。
- 最短路径问题: Floyd算法可以用于解决各种最短路径问题,例如旅行商问题。
- Floyd算法还可以用于解决图的连通性、最小生成树等问题。
实现
Floyd算法可以通过以下步骤实现:
-
初始化一个 n 阶方阵 D,其中 D[i][j] 表示从顶点 i 到顶点 j 的最短路径长度。
-
对所有顶点 i 和 j 进行迭代:
- 如果 i 等于 j,则 D[i][j] 等于 0。
- 否则,如果存在一条边直接连接顶点 i 和 j,则 D[i][j] 等于该边的权重。
- 否则,D[i][j] 等于 D[i][k] + D[k][j] 的最小值,其中 k 是任意顶点。
-
迭代结束后,D[i][j] 表示从顶点 i 到顶点 j 的最短路径长度。
例题 P1364 医院设置
设有一棵二叉树,如图:
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为 11。如上图中,若医院建在 11 处,则距离和 =4+12+2×20+2×40=136=4+12+2×20+2×40=136;若医院建在 33 处,则距离和 =4×2+13+20+40=81=4×2+13+20+40=81。
输入格式
第一行一个整数 n,表示树的结点数。
接下来的 n 行每行描述了一个结点的状况,包含三个整数 w,u,v,其中 w 为居民人口数,u 为左链接(为 00 表示无链接),v 为右链接(为 00 表示无链接)。
输出格式
一个整数,表示最小距离和
分析:这题可以用Floyd算法将医院依次按在每个节点上,再得出最小距离和 一下是有详细注释的代码
#include <stdio.h>
#include <string.h>
#define big 100000007 // 定义一个大数,表示无穷大
int p[101], dis[101][101], sum; // 定义节点权重数组、距离数组和路径和变量
int n, l, r; // 定义节点数量、左右相邻节点
int main() {
scanf("%d", &n); // 输入节点数量
memset(dis, big, sizeof(dis)); // 初始化距离数组为一个很大的值,表示无穷大
for (int i = 1; i <= n; i++) {
dis[i][i] = 0; // 自己到自己的距离为0
scanf("%d %d %d", &p[i], &l, &r); // 输入节点权重和相邻节点
if (l >= 0) {
dis[i][l] = 1; // 如果左相邻节点存在,则距离为1
dis[l][i] = 1; // 双向路,需要设置另一条方向的距离
}
if (r >= 0) {
dis[i][r] = 1; // 如果右相邻节点存在,则距离为1
dis[r][i] = 1;
}
}
// 使用 Floyd-Warshall 算法计算所有节点之间的最短路径
for (int k = 1; k <= n; k++) { //中转结点
for (int i = 1; i <= n; i++) {//起始起点
if (i != k) {
for (int j = 1; j <= n; j++) {//结束结点
if (i != j && k != j && dis[i][j] > dis[i][k] + dis[k][j]) {
dis[i][j] = dis[i][k] + dis[k][j]; // 更新最短路径
}
}
}
}
}
int minn = big;
// 计算每个节点到其他节点的路径和,找出最小的路径和
for (int i = 1; i <= n; i++) {
sum = 0;
for (int j = 1; j <= n; j++) {
if (i != j && dis[i][j] != big) {
sum += p[j] * dis[i][j]; // 计算路径和
}
}
if (minn > sum) {
minn = sum; // 更新最小路径和
}
}
printf("%d\n", minn); // 输出最小路径和
return 0;
}