[图论]Dijkstra 算法小结

来源:互联网 发布:中指数据库 编辑:程序博客网 时间:2024/06/14 08:26

Dijkstra 算法小结 

By Wine93 2013.11


1 Dijkstra 算法相关介绍

算法阐述Dijkstra是解决单源最短路径的算法,它可以在O(n^2)内计算出源点(s)到图中任何顶点的最短路,但是该算法不能处理存在负权边的图(证明中会给出)

Dijkstra一般有2种实现,一种采用邻接矩阵,复杂度为O(n^2),这种实现适用于稠密图 (边多点少),还有一种是采用临接表+heap(可用优先队列代替)实现,实现的复杂度为( m*log(n) )   (m为边数,n为顶点数),该实现适用于稀疏图(边少点多),各有各的优缺,视实际情况选择.

 算法简单证明:Dijkstra2张表(OPEN,CLOSE),我们可以认为一个表存储已经已经计算出最短路径的顶点(假设U),而另一个则存储没有计算出最短路径的顶点(假设V)Dijkstra每次都取出具有最短路径的顶点(假设NOW),视其就是该顶点的最短路.因为在当前U表中全部扩展的顶点中,NOW顶点是路径最短的顶点,也就是说,其他当前全部可以到达的顶点中,只有大于或等于NOW顶点,如果 通过这些顶点再到达NOW顶点,势必会比现在NOW顶点的路径长,因为原来就大于等于NOW顶点了所以NOW顶点路径长度就是源点到该顶点的最短路径.但是如果存在负权边,则会出现通过其他顶点到达NOW顶点的路径长度小于当前NOW顶点的路径长度,这就是为什么Dijkstra不能处理负权边了(请读者看下面例图,模拟下Dijkstra的执行过程)




2.Dijkstra的相关应用举例

.基础题

POJ 1511 Invitation Cards 

POJ 3013 Big Christmas Tre(重点在于思维的转换)


.变形题

POJ 1797 Heavy Transportation

POJ 2253 Frogger

 将这2题放在一起讲(2题都可用2分解),我们可以利用Dijkstra特殊的结构解决一类问题----单调路径(况且这么叫),所谓单调路径,即为对于任何一条路径我们所求的值只会成单调变化

POJ1797来说,每经过一条路径,weight的值只会减少(甚至不变),不会增加,看下图(边权值表示 weight,红色顶点为起点,绿色为终点,顶点下数字表示从起始点到达该顶点的weight)


我们可以发现weight呈现非递增,而我们要求的则是weight的最大值,也就是说我们求的和它的趋势相反都可用Dijkstra来题解(请看下图),这跟Dijkstra可用heap优化是异曲同工(可以认真理解证明)



如果所求值和趋势为同一走向则不能用Dijkstra求解(如最长路)


 三.好题 

 POJ 3463 Sightseeing


3.个人心得

Dijkstra的变形和应用非常多,需要一定的时间和题量积累,但是只要能深入理解Dijkstra的贪心 策略以及他在单调路径上(况且这么叫)的作用,很多问题都会迎刃而解


0 0
原创粉丝点击