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

      與前面寫的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]);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章