与前面写的Dijkstra 都是关于最短路径的算法,但是不同的是Dijkstra算法是计算单源最短路径的算法,也就是只能计算出一个点到其他点的最短路径,Floyd算法是多源最短路径算法,可以计算出任意两点的最短路径。
在讲Floyd之前先想一个问题 假设我们已经存入了一个图(如下),我们怎么缩短两点之间的距离呢?显而易见只能找中间点来作为转接点,从而达到缩短距离。这个中间点有可能是一个,有可能是两个,有可能是更多。
我们先以1作为中间点看能不能缩短其中的一些路径
1 | 2 | 3 | 4 | |
1 | 0 | 2 | 6 | 4 |
2 | ∞ | 0 | 3 | ∞ |
3 | 7 | ∞ | 0 | 1 |
4 | 5 | ∞ | 12 | 0 |
经过代码 果然有三个点缩短了
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (map[i][j] > map[i][1] + map[1][j])
map[i][j] = map[i][1] + map[1][j]
1 | 2 | 3 | 4 | |
1 | 0 | 2 | 6 | 4 |
2 | ∞ | 0 | 3 | ∞ |
3 | 7 | 9 | 0 | 1 |
4 | 5 | 7 | 11 | 0 |
那我们让他以1 和 2 为中间点是不是也能缩短?那就是在1 的基础上再判断
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (map[i][j] > map[i][1] + map[1][j])
map[i][j] = map[i][1] + map[1][j]
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (map[i][j] > map[i][2] + map[2][j])
map[i][j] = map[i][2] + map[2][j]
经过判断又有2个点缩短了
1 | 2 | 3 | 4 | |
1 | 0 | 2 | 5 | 4 |
2 | ∞ | 0 | 3 | ∞ |
3 | 7 | 9 | 0 | 1 |
4 | 5 | 7 | 10 | 0 |
那么我们让所有的点都当作转接点来判断就是Floyd算法,完整代码如下:
#include<stdio.h>
#define MAXN 999999;
int map[100][100];
void Floyd(int n){
int k, i, j;
for (k=1;k<=n;k++)//核心代码五行
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (map[i][j] > map[i][k] + map[k][j])
map[i][j] = map[i][k] + map[k][j];
}
void init(int n){
int i, j;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (i==j) map[i][j] = 0;
else map[i][j] = MAXN;
}
int main (){
int n, m, i, j, a, b, value;
scanf("%d%d",&n,&m);
init(n);
for (i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&value);
map[a][b] = value;
}
Floyd(n);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
printf("%d->%d = %d\n",i,j,map[i][j]);
}