Dijkstra算法求最短路径


以下是上面图以v0为起点的算法详细过程

1.标记V0 -- true[1]=1   初始化 Len[]={ 0 , INF , 10, INF , 30 , 100}  这里数组首元素未用到,数组下标从1开始表示V0以此类推



2.第一次循环与V0相邻的有V2、V4、V5,其中V2距离最短为10,标记V2,并且以V2为中间点(路径为V0->V2->Vx)更新最短路表,此时V3被更新为10+50=60,。


3.进入第二次循环,此时未被标记的有V1、V3、V4、V5,,其中从V0到这些的临时最短路分别为INF、60、30、100,从中找到最小的即V4,将V4标记为1,以V4为中间点(路径为V0->V4->Vx)更新最短路表,此时V3被更新为50,V5被更新为90。


4.进入第三次循环,此时未被标记的有V1、V3、V5,其中临时最短路分别为INF、50、90,从中找到最小的即V3,将V3标记为1,以V3为中间点(路径为V0->V4->V3->Vx)更新最短路表,此时V5被更新成60。


5.进入第四次循环,此时未被标记的有V1、V5,其中临时最短路分别为INF、60,找到V5,标记为1,以V5为中间点更新最短路表,此时没有元素被更新


6.进入第五次循环,这次循环没找到任何东西


7.退出循环,Len表中即为V0到其余各个节点的最短路径。


代码如下,要想输出最短路径,只需在加入最短路径集合是,保存一下该点即可。

#include<stdio.h>

#define LEN 6
#define INF 10000
#define Minx(a,b)    ((a)>(b)?(b):(a))

int Map[LEN][LEN]; //地图原始关系,结点与结点之间存在边则为边的权值,否则为INF 
int Len[LEN]; //从X到i的最短路径
int True[LEN]; //最短路径集合 

int Dijkstra(int X,int Y,int N) //Dijkstra算法求两点间最短路径 
{
int i,Min,Min_n,t = N;

True[X] = 1; //把起始点加入最短路径集合 

for(i = 0; i < N; i++)
{
Len[i] = Map[X][i]; //初始化Len,即X点到各点的距离 
}

while(t--) //循环到所有点计算一遍 
{

Min = INF;  
Min_n = 0;

for( i = 0; i < N; i++) //从没有加入最短路径集合的节点中找
{ // 从起点开始的最小边 
if(!True[i] && Len[i] < Min)
{
Min = Len[i];
Min_n = i;
}
}
True[Min_n] = 1; //把该点加入最短路径集合 

for( i = 0; i < N; i++) //以找到的最小边的节点为中间点,更新最短路径 
{
Len[i] = Minx(Len[i],Len[Min_n] + Map[Min_n][i]);
}
}

return Len[Y]; //返回起始点到Y的最短路径 
}




int main(void)
{
Map[0][0] = 0;
Map[0][1] = INF;
Map[0][2] = 10;
Map[0][3] = INF;
Map[0][4] = 30;
Map[0][5] = 100;
 
Map[1][0] = INF;
Map[1][1] = 0;
Map[1][2] = 5;
Map[1][3] = INF;
Map[1][4] = INF;
Map[1][5] = INF;

Map[2][0] = INF;
Map[2][1] = INF;
Map[2][2] = 0;
Map[2][3] = 50;
Map[2][4] = INF;
Map[2][5] = INF;

Map[3][0] = INF;
Map[3][1] = INF;
Map[3][2] = INF;
Map[3][3] = 0;
Map[3][4] = INF;
Map[3][5] = 10;

Map[4][0] = INF;
Map[4][1] = INF;
Map[4][2] = INF;
Map[4][3] = 20;
Map[4][4] = 0;
Map[4][5] = 60;

Map[5][0] = INF;
Map[5][1] = INF;
Map[5][2] = INF;
Map[5][3] = INF;
Map[5][4] = INF;
Map[5][5] = 0;

printf("%d",Dijkstra(0,3,6));

return 0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值