求多源最短路径算法当然也可以多次调用单源最短路径。
这里有另一种算法---floyd算法,相对来说也比较容易理解;
暴力循环三次,里面放一句if语句—— if(D[i][k]+D[k][j]<D[i][j]) D[i][j]=D[i][k]+D[k][j];
首先需要一个二维矩阵D[][] 它的作用是存储最短路径;例如D[i][j]的值就是i到j的最短路径长度;
还可以有一个path[][],作用跟前面求单源最短路径也是一样的,存储来时走过的路
例如path[1][3]=2; 意思是顶点1到顶点3要经过顶点2;顶点1->2->3就是顶点1到顶点3的最短路径;
在做这个算法之前还是需要初始化path数组(弄成-1)以及二维数组D(除了邻居有边的其他全为正无穷);
void floyd()
{
int i,j,k;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
path[i][j]=-1;
if(a[i][j]>0) //如果有直接相连的边
D[i][j]=a[i][j];
else
D[i][j]=MAX;//初始化为正无穷大
}
for(k=0;k<N;k++)
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(D[i][k]+D[k][j]<D[i][j])
{
D[i][j]=D[i][k]+D[k][j];
path[i][j]=k;//把它们之间的顶点记录下来
}
}
}
完整测试代码如下:
#include<stdio.h>
#include<stdlib.h>
#define MAX 10000000 //正无穷
int N;//顶点数
int E;//边数
int a[10][10];//邻接矩阵
int D[10][10];//D将存储各个点之间的最短路径,如D[i][j]的值就是i->j的最短路径
int path[10][10];//更新路径
void floyd();//多源最短路径算法
int main()
{
int i,j,x1,x2,w;
scanf("%d%d",&N,&E);
for(i=0;i<E;i++)
{
scanf("%d%d%d",&x1,&x2,&w);
a[x1][x2]=a[x2][x1]=w;//给每条路赋予权重 这里假设权重即路径(大于0)
}
floyd();
for(i=0;i<N;i++)
D[i][i]=0;//自己到自己路径长度为0
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
printf("顶点%d到顶点%d的最短路径是:%d\n",i,j,D[i][j]);
}
return 0;
}
void floyd()
{
int i,j,k;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
path[i][j]=-1;
if(a[i][j]>0) //如果有直接相连的边
D[i][j]=a[i][j];
else
D[i][j]=MAX;//初始化为正无穷大
}
for(k=0;k<N;k++)
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(D[i][k]+D[k][j]<D[i][j])
{
D[i][j]=D[i][k]+D[k][j];
path[i][j]=k;
}
}
}