数据结构——Dijkstra(邻接矩阵)

最短路径

问题:
用带权的有向图表示一个交通运输网,图中:

  • 顶点——城市
  • 边——城市之间的交通联系
  • 权——线路的长度或沿此路线运输所花的时间或费用等

问题:从某顶点出发,沿图的边到达另一个顶点所经过的路径中,各边上权值之和最小的一条路径——最短路径

Dijkstra算法

算法思想:

(以下内容复制度娘)
按路径长度递增次序产生算法:
把顶点集合V分成两组:
 (1)S:已求出的顶点的集合(初始时只含有源点V0)
 (2)V-S=T:尚未确定的顶点集合
将T中顶点按递增的次序加入到S中,保证:
 (1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度
 (2)每个顶点对应一个距离值
S中顶点:从V0到此顶点的长度
T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度
依据:可以证明V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和

举例:

在这里插入图片描述
第一步:
S集合:V0
T集合:V1,V2,V3,V4,V5
下表中∞表示两个点之间无联系

顶点 V1 V2 V3 V4 V5
权值 10 30 100

选出权值最小的一个结点,为V2,权值为10
第二步:
S集合:V0,V2
T集合:V1,V3,V4,V5

顶点 V1 V2 V3 V4 V5
权值 10 30 100
权值 60 30 100

选出权值最小的一个结点,为V4,权值为30
注意,这里的V3对应的权值为60是v0到V2的权值加上V2到V3的权值
第三步:
S集合:V0,V2,V4
T集合:V1,V3,V5

顶点 V1 V2 V3 V4 V5
权值 10 30 100
权值 60 30 100
权值 50 90

选出权值最小的一个结点,为V3,权值为50
注意,这里的V3对应的权值为50是V0到V4的权值加上V4到V3的权值,也就是说,之前的路线不如现在的路线快捷
第四步:
S集合:V0,V2,V4,V3
T集合:V1,V5

顶点 V1 V2 V3 V4 V5
权值 10 30 100
权值 60 30 100
权值 50 100
权值 60

选出权值最小的一个结点,为V5,权值为60
第五步:
S集合:V0,V2,V4,V3,V5
T集合:V1

顶点 V1 V2 V3 V4 V5
权值 10 30 100
权值 60 30 100
权值 50 100
权值 60
权值

至此所有的步骤也就结束了
通过最后一个表可以看到从V0到各个顶点对应的最小权值和,V1最后的∞表示无法从V0到V1
Dijkstra算法实现的代码在网上一搜有很多,主要的代码步骤为:

  1. S = { 源点 }
  2. for (i=1;i<n;i++) D[i] = c[源点,i] //D[i]为源点到各个顶点的权值和,c[源点,i]表示源点到顶点i的边长
  3. for(i=1;i<n;i++){
    在V-S中选择一个结点W,使得D[w]最小,将W加入集合S
    for(每一个在V-S中的结点V) D[v] = min(D[v], D[w]+C[w,v];
    }

但老师布置的作业里,增加了一个路径的求法。
目前我的思路是,每一次都列出当前步骤最后求出的最小权值对应的顶点所对应的路径,在下一步里,如果某个顶点的权值和发生了变更,那就说明它使用到了上一步列出来的那个路径,那么,它的路径就会更改为上一步列出来的路径
听上去有点绕,举个例子:
比如V0到V3:

  • 第一步中,权值和最小的是10,对应的是V2顶点,那么最短路径为V0->V2
  • 第二步中,V0到V3的权值和发生了变化,从∞更改到了60,说明它用到了步骤一里V0->V2这一条路径,那么它自己的路径就要变成V0->V2->V3,而对应的比如V4,它的权值和依旧是30,它的路径也依旧是V0->V4.这一步骤结束后,权值和最小的是30,对应的是V4顶点,那么最短路径为V0->V4
  • 第三步中,V0到V3的权值和再次发生了变化,从60更改到了50,说明它用到了步骤二里V0->V4这一条路径,那么它自己的路径就要变成V0->V4->V3,注意的是,它的路径里不再包有V2结点

那么在代码里,我使用了以下几个变量:

名称 作用
vector< string> S 已求出的顶点集合
vector< string> T 未求出的顶点集合
vector<vector< string> > result(G.vexnum) 对应的路径
VRType distance[G.vexnum] 源点到各个顶点的权值和
vector< string> process 每一步里权值和最小的顶点对应的路径
string p 最小权值和对应的结点
weight 最小权值和

process初始放入一个源结点,p初始化也为源结点,weight初始化为0

具体代码如下:

int getindex(MGraph &G, string u)
{
   
   
    int min = 100000;
    int u_index;
    for(int i=0;i<G.vexnum;i++){
   
   
        if(!u.compare(G.vexs[i])){
   
   
            u_index = i;
            break
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值