Johnson多源负权最短路
Johnson多源负权最短路
Floyd算法复杂度是 \(O(n^3)\),然而dij的复杂度只是 \(O(mlogm)\)。
所以对于稀疏图来说,对每个点跑dij就已经比Floyd快了。
但是dij有一个缺陷:它不能处理有负权的图,于是Johnson算法应孕而生。(我认为是这样的)
Johnson算法流程:
- 我们设一个虚拟节点为 \(0\) ,从这个点向其他所有点连一条边权为\(0\)的边。
- 求出从 \(0\) 到其它点的最短路为 \(h[i]\)。
- 对于每条边边权设为 \(w+h[u]-h[v]\) 。
- 最后再对每个点跑dij,不过 \(x\) 到点 \(y\) 的距离为 \((dis_{i->j}-h_i+h_j)\)
因为先用spfa跑了最短路,所以 \(w+h[u] >= h[v]\) 一定成立。
再考虑正确性:现有一条路径:a->b->c
计算得答案为 disa->b + h[a] - h[b] + disb->c + h[b] - h[c] == disa->b + disb->c + h[a] - h[c]
容易发现路径上的h值都抵消掉了,只剩下了头和尾,而头和尾的h值是确定的,所以原来的最短路和处理后的最短路是同一条(至少处理后值一样)。