Johnson全源最短路算法

我们最熟悉的全源最短路算法那肯定是Floyd。

不过Floyd的复杂度是 O ( n 3 ) O(n^3) O(n3),显然难以接受。

当图比较稀疏的时候,即点数n和边数m同阶时,Johnson算法便有了用武之地。

假设图没有负边,则可以直接用堆优化的dij跑n次,时间复杂度为 O ( n ∗ ( ( n + m ) l o g m ) ) O(n*((n+m)logm)) O(n((n+m)logm))

如果有负边,考虑将图V转换为V’,V’的边权为非负,且V的最短路集=V’的最短路集。

建立超级源S,到每个点连长度为0的边。

用SPFA以S为起点跑最短路,设f(x)为到x的最短距离。

若有边 ( x − > y   c o s t : z ) (x->y ~cost:z) (x>y cost:z),则新的边权为 z − ( f [ y ] − f [ x ] ) z-(f[y]-f[x]) z(f[y]f[x])

证明:
1.边权非负
由最短路性质:
若有 ( x − > y   c o s t : z ) (x->y ~cost:z) (x>y cost:z),则 f [ y ] − f [ x ] < = z f[y]-f[x]<=z f[y]f[x]<=z,得 z − ( f [ y ] − f [ x ] ) > = 0 z-(f[y]-f[x])>=0 z(f[y]f[x])>=0
可知新的边权非负。

2.最短路不变
若有路径 x 1 − > x 2 − > x 3 … − > x n x1->x2->x3…->xn x1>x2>x3>xn
原路径为 z 1 + z 2 + … z [ n − 1 ] z1+z2+…z[n-1] z1+z2+z[n1]
则新路径为 ( z 1 − ( f [ x 2 ] − f [ x 1 ) ] ) + ( z 2 − ( f [ x 3 ] − f [ x 2 ] ) ) + … + ( z [ n − 1 ] − ( f [ x n ] − f [ x n − 1 ] ) ) (z1-(f[x2]-f[x1)])+(z2 - (f[x3]-f[x2]))+…+(z[n-1]-(f[xn]-f[xn-1])) (z1(f[x2]f[x1)])+(z2(f[x3]f[x2]))++(z[n1](f[xn]f[xn1]))
= z 1 + z 2 + … z [ n − 1 ] − f [ x n ] + f [ x 1 ] =z1+z2+…z[n-1]-f[xn]+f[x1] =z1+z2+z[n1]f[xn]+f[x1]
f [ x n ] − f [ x 1 ] f[xn]-f[x1] f[xn]f[x1]为关于起点终点的常数,所以最短路不变。

你可能感兴趣的:(最短路径,模版,SPFA)