简单介绍
- 这个算法可以用来求一个图中任意两个点的最短路径,也被称为 “多源最短路径” 问题
讲解
- 我们可以用二维数组来存储各点间的距离信息,将没有办法直接到达的用无穷大来表示,自己到自己用0来表示,这样我们就得到了图的信息
- 但如何求两点间的最短路径?
- 如图,是储存好的一张图(图有四个点,八条边)
- 从图可以知道,我们并不能从2点直接到1点,但我们可以借助一个中转站,如我们可以先从2点到3点,距离为3,然后从3点到1点,距离为7,这样我们便有知道了2点可以通过9的距离到达1点
- 从图还可以得到,1点直接到3点的距离为6,但我们通过2这个中转点,便能将距离缩短为5
- 通过上面这例子,我们便知道了每个顶点都有可能使另外两个顶点的路程变短,但我们不能毫无目的的寻找
- 假如现在只允许经过一号顶点,求任意两点间的最短路程只需判断e[i][1]+e[1][j]是否比e[i][j]小
代码实现
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(e[i][1]+e[1][j]<e[i][j])
e[i][j]=e[i][1]+e[1][j];
}
}
最短路程更新如下:
- 然后2号顶点加进来,看只允许1,2号点做中转点的情况能使那些距离改变,再依次增加,看1,2,3点做中转点,1,2,3,4做中转点可以改变的距离
- 下面是整个算法的核心代码(只有5行)
for(k=1;k<=n;k++){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(e[i][k]+e[k][j]<e[i][j])
e[i][j]=e[i][k]+e[k][j];
}
}
}
完整代码
#include<stdio.h>
#define MAX 999999
int main(){
int e[10][10],i,j,k,n,m,t1,t2,t3;
scanf("%d %d",&n,&m);//输入点的个数和边的条数
//初始化数组
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j)
e[i][j]=0;
else
e[i][j]=MAX;
}
}
//读入各边的距离
for(i=1;i<=m;i++){
scanf("%d %d %d",&t1,&t2,&t3);
e[t1][t2]=t3;
}
//核心算法
for(k=1;k<=n;k++){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(e[i][k]+e[k][j]<e[i][j])
e[i][j]=e[i][k]+e[k][j];
}
}
}
//输出图
/*for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
printf("%d ",e[i][j]);
}
printf("\n");
}*/
//输入想知道最短距离的两个点
scanf("%d %d",&i,&j);
printf("点%d和点%d的最短距离是:%d",i,j,e[i][j]);
return 0;
}