浅析dijskra算法(含dijskra算法队列优化和链式前向星存图)

之前写过最小生成树的相关文章,介绍了两种生成最小生成树的相关算法。单源最短路径一直是信息竞赛中常见的问题,有各种变形和拓展。今天就先介绍一下dijskra算法,同时说一下队列优化和存图方式之链式前向星。

Dijskra算法介绍:
该算法的提出时间啊,相关历史啊,发明者啊啥的我也不一一介绍了,这对于我们理解该算法并没有什么卵用。我直接用最简洁的口语来描述该算法,尽量不用任何学术术语,好让小白也能看懂。
先说一下dijskra算法的适用范围:没有负权的边。
dijskra算法我在刚开始看的时候有点迷,到后来想明白一点之后我就不迷了:A->…->B->…->C是A到C的一条最短路径,那么这条路径中经过B点,在这条路径中A到B的路径也是A到B的最短路径,即:一条最短路径中包含路过的所有节点的最短路径,明白这一点之后,就知道了,dijskra算法的本质其实是贪心算法,毕竟存在最优子结构嘛,而且局部最优解最终可以构成全局最优解。
下面开始介绍算法:
d 代表最短路径的距离。
假设从A点出发,要求计算出A到所有点的最短路径。一定有若干个点可能的最短路径是知道的,这些点就是与A直接相连的点(不直接相连的统一初始化为正无穷),然后把这些点的d都记为与A直接相连边的长度,注意,此时这些d并不一定是最终的结果,但是这些d中最小的一定是该点的最终结果,(这些拥有d且d不为正无穷,也就是已经存在可能的最短路径的点都保存在某种数据结构中,比较常用的是一维数组或者是队列)。取出这中最小的d的点,然后对该点进行处理,计算所有该点能到达的点的可能的最短路径,也就是min(d+w(i,j),d)(有两种情况,一种是d原为正无穷,一种是d已经计算出来过一个可能的最短路径,这两种情况都是取最小)对该点处理完之后,数据结构中又拥有了新的点,取出这些新的点中d最小的点,重复上述过程,最终就可以算出所有的最短路径了(注意某个点的最短路径计算出来之后一定要标记,免得不断重复计算)。
Dijskra算法流程图解(图片来源于百度)
dijskra算法我就介绍到这里,该算法还有两个相关问题,就是怎么存图以及如何找到d最小的点。在刷题的过程中,如果用邻接矩阵在存放图,显然是不现实的,因为往往体中给的数据都是100000个点,你开一个100000×100000的二维数组显然是不可能的,那就要用到链式前向星了,关于链式前向星,有大佬的文章写的非常详细,在此附上链接:

链式前向星详解

利用链式前向星,我们可以非常节约空间地来保存一个图,这个图可以是无向图,也可以是有向图。

然后就是如何找到已保存地点中哪个点的d最小。要是用一维数组的话可以循环一个个对比,但这显然效率太低,C++为我们提供了一种神奇的队列:priority_queue 由于链式前向星往往把边用结构体保存,因此这里附上相关用法的链接:

priority_queue

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值