c++ 最短路 小总结

之前学习了一些最短路的知识点,在此做一个小总结。

单源最短路径

单源最短路径问题是指在一个带权图中,给定一个源顶点,计算从该源顶点到图中所有其他顶点的最短(即路径上所有边的权重之和最小)路径及路径权重的问题,在这里介绍3种算法。

Dijkstra算法

首先,我们需要用一个数组dis 来记录到目前为止起点到各顶点的最短路径长度。执行的步骤如下:

(1)在初始时刻,先将整个数组dis 设为 inf(即无穷大)。
(2) 对于一条从顶点u到v、长度为w的连边,如果 dis[u]+w <dis[v], 那么就可以将dis[v]的值变成dis[u] +w,因为这代表着从起点、走到顶点u,经过这条边再走到顶点v,是一条未发现过的且比原先的最优路径还要短的边。这样的操作被称为松弛。因为dis[s(就是源顶点)]=0,所以dis[s]一定不会再被“松弛”了,所以可以松弛所有s的出边后将s标记。
(3)可以发现前面操作进行完之后将会有一个点的dis 值是当前未标记的点中最小的。由于从s走来的边已经全部完成松弛,且其余未标记边的dis值都大于该边的dis值(这意味着从其他点走到该点的边都无法成功松驰),所以此时的该点的dis值就是最短路。接着就可以用与该点相连的所有边进行松驰并将该点标记。
(4)不断重复进行(3)操作,直到没有从已标记点到未标记点的边。

其过程概括如下:

(1) 将起始点的dis置为0。
(2)选择当前未标记的顶点中dis 值最小的一个。
(3)对该顶点的所有连边依次进行松弛操作。
(4)对该顶点进行标记。
(5) 重复第(2)步至第(4)步,直到不存在一条从已标记顶点通往未标记点的连边。

对于此算法,时间复杂度是O(n^2+m),对于稀疏图来说,每一次循环都要将n条边遍历一遍来找最小,可能较高,不适应某些情况。对此,可以使用优先队列来优化。

首先,使用一个小根堆来维护dis最小的结点。用结构体记录结点编号i和dis[i],并通过重载运算符以dis为关键字进行排序。每次松弛成功时,将被松弛的边的终点和对应的dis值打包放入堆中,在需要寻找di

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值