dijsktra算法

单源最短路径算法,用于找出一个点与其他点的最短路径,只能用于不带负权边的图,适合于稠密图(边多的图)

算法思路

本质上是贪心算法,其思路是维护一个初始集合S,里面的元素代表已经确定了最短路的点,设所有点集合为V,每次循环从V-S集合中挑选此刻到源点最近距离的点,将此点加入S中,并更新所有此刻未被加入到S集合中的点到源点的距离(松弛),当V=S时,循环终止

算法证明

设初始集合S,dist[u]:当前u点经过S中的点到源点的距离,short[u]:u点到源点的最短距离(可以不经过S中的点)
使用数学归纳法进行证明,当算法进行到第k步时,S中的每个结点i有dist[i]=short[i]成立时,k+1步同样成立
n=1时,S={源点}, dist[源点] = short[源点] = 0 正确
n=k+1时,假设此时选取的结点为v,v点为源点经过S距离最短的点。
假设此时有另一条路径L,L经过S中的最后一个点为x,经过V-S中的一个点y后到达点v,此时dict[y]>=dict[v],那么dict[y]+w(y,v)>dict[v],即不存在其他能够到达v的其他路径,那么此时dist[v]=short[v]
在这里插入图片描述

说明下为啥这个算法是正确的

我们还是假设有一个空集合S,dict[v]表示v到源点的距离
1.先将源点s移动到S中,毫无疑问dict[s]=0,为到源点距离最小的点
2.选取除源点s外dict最小的点,此点因为是第2个点必定与源点直接相连,且一定是到源点的最短路径,因为如果不是最短路径,则此时还会有比当前dict更小的dict。通过第2个点更新其他点到源点的距离,并将第2个点加入S中
3.选取第3个点,其在剩余点中dict最小,此点有可能并不与v直接相连。如果此点能不经过S成为最短路径,那么在第1,2步的时候选取dict的时候毕竟不会选第1,2个点,所以此点的最短路径一定通过S。那么最短路径要么经过第1个点,要么经过第2个点,而这两个值的最小值已经在选取第2个点时被求出了,即dict的值,此时dict一定是最短路径
看懂上面说的就能明白为什么通过这样的松弛就能得出最后的最短路径了,实际上在选取第n个点对其他点进行松弛时,1…n-1个点的松弛结果已经反馈到了第n个点的松弛上

代码模板:
int d[maxn], vis[maxn], g[maxn][maxn];
void dijkstra(int k){
   
	memset(d, 0x3f, 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值