正权图单源最短路(SSSP)- Dijkstra算法

引言:

DAG上的最短路可以用dp解得,容易得到状态转移方程。但如果图中可以有环,就要使用其他算法了。这里先考虑边权均为正的最短路问题。

 

Contents:

一、 普通的dijkatra实现  O(n2)

二、采用邻接表

三、 基于优先队列的Dijkstra O(mlogn)


 给出样例问题(图片引自Tanky Woo):

对下图中的有向图,用Dijkstra算法计算从任意源顶点到其它顶点间最短路径。

输入:

6
7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
1
2
3
4
5
输出:
No.1->No.5 :60
No.2->No.5 :60
No.3->No.5 :10
No.4->No.5 :30
No.5->No.5 :0

接下来就此问题,分别介绍几种复杂度不同的实现方法。


一、 普通的dijkatra实现

首先来谈谈这个算法。记st为起点,dist[i]为结点 i 到st的最短路径长。

初始化dist[st] = 0; 其余dist为INF(类似maxint)。当前结点 u = st。

从当前点u出发遍历邻点,更新dist[v] = min{ dist[v], dist[u]+w[u][v]};  ----------这里有点像状态转移

设一个集合S,总是把当前不在S中的结点的最小dist对应的点加入S中。

当所有点都在集合S中时,完毕。此时dist数组更新完毕,即从st到图上任意结点的最短路长都已经算出。

 

理解:关键在于集合S,每次取当前最小的dist。可见取到S中的点的dist都是已经更新完毕的了,即已算出的。

可以用反证明法想想,如果某次dist[i]是最小的dist,但是st到 i 还存在经过 u' 的更短的路,则

dist[u']必然 小于dist[i],即u'会比 i 先成为当前点,那时dist[i]就会在u'作为当期点的时候被更新为

dist[u']+w[u'][i]了。 所以,dist[i]必是st到 i 的最短路长。

 

每次取一个元素到S中,所以循环n-1次,每次循环时,求最小dist(遍历n个结点)和更新相邻dist值(若采用邻接矩阵)都是O(n)的,所以时间复杂度为O(n^2)。

 

这里附上其他说法࿰

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值