Johnson算法最短路O((V^2)lgV+VE) 任意两点间的最短路
在介绍johnson之前,咱们复习一下常见的最短路的算法吧
(1)单对单,单对多
1 、dijkstra算法,O(V)的入堆 , O(V)的预处理,O(VlgV)从堆中出最小值 , O (ElgV)E 次松弛,修改堆,每次lgV
用斐波那契堆的话 O(V)的入堆 , O(V)的预处理,O(VlgV)从堆中出最小值 , O (E)E 次松弛,修改堆,平摊O(1 )
局限,不能处理负权值O(E+ VlgV)
2 、Belloman_Ford , O(VE) , V-1次每次对E条边进行松弛 ,如果没有dist 的更新退出
它的变种优秀的算法spfa , 平均时间是O (kE),k是小常数 ,不过也会有最坏的情况,当一个元素入队V次就表示有负权环
可以处理负权和负权环的最短路
3 .没有环的最短路径问题 拓扑排序O ( V +E ) 局限性,只能是没有环的
(2)多对多
前面都可以,执行V次即可
还有动态规划的floyd算法O(n^3)算法
斐波那契堆+dijkstra O ( VE+ V^2lgV ) 对于稀疏图,比floyd 优,不过不能出现负权值
然后就是 O ( VE+ V^2lgV ) 可以出现负权值,和负权环
哈哈哈,咱还是接着写吧,johnson算法其实是dijkstra的变种,它的思想就是将每条w (u,v)映射到 ww( u , v )
使得ww ( u , v )恒为非负 , 然后通过 dijkstra斐波那契堆,实现,然后再映射回去
我们 定义 ww ( u, v )= w (u, v) + h( u ) - h ( v ) 为什么这么做,后面会说的
然后我们先证明
ww ( u, v ) 的最短路,对应这 w (u , v ) 的最短路
假设 u-> x1->x2 ->x3 ->----xn->v 为 ww ( u , v) 的最短路
dist [ u , v ] = ww ( u , x1 ) + ww ( x1 , x2 ) + ww ( x2 , x3 ) + ww ( x3 , x4 ) + --- + ww( xn, v )
= w ( u , x1 ) + h ( u ) - h ( x1 ) + w ( x1 , x2 ) + h ( x1 ) - h ( x2 ) + w ( x2 , x3 ) + h ( x2 ) - h ( x3 ) +
--- + w ( xn , v ) + h ( xn ) - h ( v )
= w ( u ,x1 ) + w (x1 , x2 ) + w ( x2 , x3 ) + --- + w ( xn , v ) + h ( u ) - h ( v ) = d [ u , v ] + h [ u ] - h [ v ] ;
其中 w ( u ,x1 ) + w (x1 , x2 ) + w ( x2 , x3 ) + --- + w ( xn , v )为 w (u , v ) 中 d [ u , v ] 的最短路
所以两者一一对应,
然后
若 w ( u, v ) 中存在负权环, 对应这 ww(u , v ) 也存在负全环
方面和下面一样 只是 u= v了。
那么怎么构造 h (u)
我们增加一个节点s,将它向V 中的每个节点 连一条边 ,边的权值为 w ( s , V ) = 0
那么我们以s 为源点做一次 belloman_ford O ( VE ) 将ddd [ s , v ] = h ( v ) ,出现负权环,就输出图中有负权环,所以结束程序
其他情况继续, 由于 对于任意有向边 ( u, v)都有 ddd [ u ] + w ( u , v ) >= ddd [ v ] ,否则可以进行松弛。(因为不会有负权环发生) ,所以移项 w ( u , v ) + ddd [ u ] - ddd [ v ] >=0 如果同h [ u ] = ddd [ u] ,那么就变为 w ( u , v ) + h ( u ) - h ( v ) 了,所以能够得到
ww( u , v ) 接下来就是V次斐波那契堆+dijkstra
最后d [ u , v ] = dist [ u , v ] + h [ v ]- h [ u ] 即可得到真实的最短路值