学习笔记: 图的最短路径

图的最短路径

带权图的最短路径

从某顶点(源点)出发到另一顶点(目的点)的路径中,有一条各边(或弧)权值之和最小的路径称为最短路径。

  1. 从单源点到其余各点的最短路径 迪杰斯特拉算法(Dijkstra)
  2. 每一对顶点之间的最短路径 弗洛伊德算法 (Floyd)

迪杰斯特拉(Dijkstra)算法

迪杰斯特拉(Dijkstra)算法:

依最短路径的长度递增的次序求得各条路径。

其中,从源点v0到顶点vi的最短路径是v0到各点路径集合长度中长度最短者。

路径长度最短的最短路径的特点:

在这条路径上,必定只含有一条弧,并且这条弧的权值最小。(设为v0->vk)

下一条路径长度次短的最短路径特点:

它只可能有两种情况:或者是直接从源点到该点vi(只含一条弧);或者是从源点经过顶点vk,再到达vi(由两条弧组成)。

再下一条路径长度次短的最短路径特点:

它可能有两种情况:或者是直接从源点到该点(只含一条弧);或者是从源点经过顶点vk,vi再到达该顶点(由多条弧组成)

其余最短路径:

它或者是直接从源点到该点(只含一条弧);或者是从源点经过已求得最短路径的顶点,再到达该顶点

在这里插入图片描述

迪杰斯特拉(Dijkstra)算法的基本思想:

  1. 初始时,集合S中仅包含源点v0,集合V-S中包含除源点v0以外的所有顶点。v0到V-S中各顶点的路径长度或者为某个权值(如果它们之间有弧相连),或者为无穷(没有弧相连)。
  2. 按照最短路径长度递增的次序,从集合V-S中选出到顶点V0路径长度最短的顶点vk加入到S集合中。
  3. 加入vk之后,为了寻找下一个最短路径,必须修改从v0到集合V-S中剩余所有顶点vi的最短路径。若在最短路径上加入vk之后,使得v0到vi的路径长度比原来没有加入vk时的路径长度短,则修正v0到vi的路径长度为其中较短的。
  4. 重复以上步骤,直至集合V-S中的顶点全部被加入到集合S中为止。

存储结构

  1. 带权邻接矩阵用g.arcs[ ] [ ]表示:

    用g.arcs[i] [j].adj表示弧<vi,vj>上的权。

  2. 将顶点分为两组:S,V-S

    S中存放已求得最短路径的终点的集合。

  3. 借助辅助一维数组dist[ ]

    若vi属于S,dist[i]表示源点到vi的最短路径长度

    若vi属于V-S,dist[i]表示源点到vi的只包括S中的顶点为中间顶点的最短路径。

    初始:S={v0},v0为源点

    ​ dist[i]=g.arcs[0] [i].adj; (vi属于V-S)

  4. 二维数组path[] [ ]记录某顶点是否加入到集合S中

    如果path[i] [0] = 1,

    则表示顶点vi加入到集合S中,并且path[i]所在的行最终记录了源点到vi的最短路径上的各个顶点。

    否则,path[i] [0]=0,则表示顶点vi还在集合V-S中。
    在这里插入图片描述

代码实现:

void <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿小张的日常笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值