终于学到求最短路了,终于来到我最喜欢的算法——Floyd-Warshall了!今天还有点小激动呢!
我喜欢它,当然是因为它逻辑十分简单咯!真的只有5行诶!
Floyd-Warshall算法
题目描述
暑假,小哼准备去一些城市旅游。有些城市之间有公路,有些城市之间则没有,如下图。为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程。
核心思想
对于一个用邻接矩阵存好的图,对于每一个点,将它作为转车点,然后再对每个点进行遍历,如果距离小于转机(直走还不如转车的情况下)就更新这段“直走”的值。
核心代码:
//快乐的Floyd-Warshall核心语句
for (k = 1; k <= n; k++) //k是被中转的点
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (a[i][j] > a[i][k] + a[k][j])
a[i][j] = a[i][k] + a[k][j];
完整代码:
#include<stdio.h>
int a[2000][2000];
int inf = 99999999;
int main()
{
int i, j, k, m, n, x, y, s;
scanf("%d %d", &n, &m);
/* */
//初始化
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (i == j)
a[i][j] = 0;
else
a[i][j] = inf;
//读入边(有向图)
for (i = 1; i <= m; i++)
{
scanf("%d %d %d", &x, &y, &s);
a[x][y] = s;
}
printf("原地图:\n");
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
printf("%9d ", a[i][j]);
}
printf("\n");
}
//快乐的Floyd-Warshall核心语句
for (k = 1; k <= n; k++) //k是被中转的点
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (a[i][j] > a[i][k] + a[k][j])
a[i][j] = a[i][k] + a[k][j];
printf("Floyd-Warshall边松弛结果:\n");
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
printf("%9d ", a[i][j]);
}
printf("\n");
}
return 0;
}
运行结果: