Floyd 算法----只有5行的算法

      与前面写的Dijkstra 都是关于最短路径的算法,但是不同的是Dijkstra算法是计算单源最短路径的算法,也就是只能计算出一个点到其他点的最短路径,Floyd算法是多源最短路径算法,可以计算出任意两点的最短路径。

      在讲Floyd之前先想一个问题 假设我们已经存入了一个图(如下),我们怎么缩短两点之间的距离呢?显而易见只能找中间点来作为转接点,从而达到缩短距离。这个中间点有可能是一个,有可能是两个,有可能是更多。

 

我们先以1作为中间点看能不能缩短其中的一些路径                                                      

 1234
10264
203
3701
45120

经过代码 果然有三个点缩短了

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]
 1234
10264
203
37901
457110

那我们让他以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个点缩短了

 1234
10254
203
37901
457100

那么我们让所有的点都当作转接点来判断就是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]);
}

 

点赞