思考一个问题,在一个含权有向图中,顶点1为源点(可以到达图中任意点,但图中任意点都不能到达此点),想办法求出顶点1到图中所有点的最短路仅(只求处路径长度).
思路如上面截图所示:代码如下
#include <stdio.h>
#define M 7
#define INFINITY 9999999
int findMin(int *lamda,int *Y);
void DIJKSTRA(int g[][M],int lamda[M]);
void printWay(int point,int current);
int way[M]={0};
int main(void)
{
int g[M][M]={0},lamda[M]={0},i=0,j=0;
for(i=0;i<M;i++)
{
for(j=0;j<M;j++)
{
if(i==j) g[i][j]=0;
else g[i][j] = INFINITY;
}
}
g[1][2] = 1,g[1][3] = 12;
g[2][3] = 9,g[2][4] = 3;
g[3][5] = 5;
g[4][3] = 4,g[4][5] = 13,g[4][6] = 15;
g[5][6] = 4;
DIJKSTRA(g,lamda);
for(i=1;i<M;i++)
{
printf("源点到顶点%d的距离是:%4d 路径是:",i,lamda[i]);
printWay(i,i);
printf("\n");
}
return 0;
}
void DIJKSTRA(int g[][M],int *lamda)
{
int X[M],Y[M];
int i=0,j=0,k=0;
X[1] = 1,lamda[1] = 0; //起始阶段X数组中只有1,Y数组中只没有1
for(i=2;i<M;i++) Y[i] = 1;
for(i=2;i<M;i++)//初始时,靠近1的全部记录
{
lamda[i] = g[1][i];
}
for(i=2;i<M;i++)
{
int y = findMin(lamda,Y);
X[y] = 1; //将y添加入X数组
Y[y] = 0; //将y剔除Y数组
if(!way[y]) way[y] = 1;
for(j=2;j<M;j++) //更新1点到j点的距离
{
if(Y[j]&&(lamda[y]+g[y][j])<lamda[j])
{
lamda[j] = lamda[y]+g[y][j];
way[j] = y;
}
}
}
}
//寻找lamda数组中的最小值,并且这个点不存在与X数组中
int findMin(int *lamda,int *Y)
{
int i=0,j=0,min = INFINITY;
for(i=2;i<M;i++)
{
if(lamda[i]<min&&Y[i])
{
j = i;
min = lamda[i];
}
}
return j;
}
void printWay(int point,int current)
{
if(point==1)
{
printf("%d ->",1);
if(current==1) printf("%d",1);
return;
}
else
{
printWay(way[point],current);
if(point!=current)
printf(" %d ->",point);
else
printf(" %d",point);
}
}