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