Dijkstra算法证明图解

前言:

Dijkstra算法算是比较经典的一个求单源最短路径的一个算法了,有向图和无向图都可以使用,对于采用邻接表还是邻接矩阵存储图也没有要求。

我在一开始学习这个算法的时候,虽然知道算法的具体处理流程,但是对于算法的原理却是一知半解,在做PTA一些算法题的时候遇到了稍微灵活的题目就歇菜了。所以翻看了一写文档,自己归纳整理了一下原理,也有一些自己的想法,如有不当之处,还望批评指正。

算法步骤

参数说明

start : 出发结点
end : 终点
S : 已确定最短路径的结点集合

算法描述

1.按题目要求建立邻接矩阵或者邻接表,将start放入S。

2.将所有结点在经过S中的结点到达start的距离放入lowcast数组(用于存放最短路径的长度)。

3.在lowcast数组中找到距离start最近且未在S中的结点Vi,将Vi收录进S,并更新和Vi有直接边相连的结点的lowcast的值(如果经过Vi离start更近,则更换lowcast为经过Vi的路径)。

4.重复步骤2,3,直到所有的的结点被收录进S。

算法过程图解

单源无向图:
在这里插入图片描述第一步:
在这里插入图片描述

第二步:
在这里插入图片描述
第三步:
在这里插入图片描述第4步:
在这里插入图片描述第5步:

在这里插入图片描述第6步:
在这里插入图片描述

算法可行性证明

一.数学归纳法:

假设前提:

1.有x个结点,lowcast为一个长为x的数组,lowcast的数组初始化为所有顶点经过S(已确定最短路径的结点集合,初始为∅)到达start的距离。
2.图为无向连通图。

可得lowcast有三种情况:

①没有和S中任何结点有边相连,值为inf
②start结点本身,值为0。
③与S中的编号为i结点有直接边相连,值为min{lowcast[x]+map[x][v]|x∈i}

归纳证明:

证明目标:
第n个被收录进S的结点一定已经找的了最短路径。

①当n=1时,即与start有直接边相连的结点距离start的最短路径,最短路径为与start直接相邻的边。当该结点V被收录进了S,与V直接相连的结点可以通过V到达start,所以需要更新与V有直接边相连的结点的lowcast的值。

②假设当n等于k时,所有S中的结点都已经找到了最短路径,所以当n为k+1时,寻找lowcast的最小值的节点V,该V必然与S中的结点有直接边相连(如果没有直接边,则距离start必为inf,而inf又是最小值,图一定不为连通图,与假设矛盾),因为S中的路径已经保证为最优路径,所以

L=min{distance{V->Vs}+lowcast(Vs)}(Vs为S中与V有直接边相连的结点)

就是V到start的最短路径长度,而L的计算已经在上一轮操作完成,即是lowcast的更新。
所以假设成立,证毕。

二.贪吃蛇法(个人理解):

首先需要理解S是一个确定的集合,经过S的n个节点后到达start都可以理解为经过一个S到达start。很好理解,这里我不做证明
在这里插入图片描述1号结点被收录进S
在这里插入图片描述2号结点被收录进了S
在这里插入图片描述4号结点被收录进了S
在这里插入图片描述
3号结点被收录进了S
在这里插入图片描述由上图图方法可得最短路径。

PTA题目:

这篇文章是我在pat上做题时遇到了一个dijkstra算法的题目,想到自己大一虽然学了这个算法,也敲了好几遍代码了,但是总的思想还是不清晰,在pta上遇到时花了很多时间才AC,所以写了一篇博客整理了一下dijkstra算法的思路。其实这个算法不难,主要是理解数归法,或者说贪心+动态规划算法的思路,其实本质都差不多。
另外我写了一个注释较全的一个关于dijkstra算法的题解,对上面理解不清晰的话可以结合题目看。

PTA题目:紧急救援

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值