【图论】浅谈JohnSon全源最短路
前置知识
SPFA、Dijkstra.
引文
先是给一道题目:
给定一个包含 n 个结点和 m 条带权边的有向图,求所有点对间的最短路径长度,一条路径的长度定义为这条路径上所有边的权值和。
看到最短路,你也许会想到最短路;
然而发现它居然会有负边,也就是说可能会有负环,你便可能想到 SPFA 或是 Floyd,
但是时间复杂度一个为 \(O(n^2m)\) ,一个为 \(O(n^3)\) ,都不能很快的通过此题,
这便需要我们用到 \(JohnSon\) 全源最短路算法了。
正文
首先我们可以发现,
设 \(dis_x\) 为 \(x\) 与起点之间的最短路,
\(w_{x,y}\) 为 \(x\) 与 \(y\) 之间的边权,
则有当 \(x -> y\)
\(dix_x <= dix_y + w_{x,y}\)
\(dis_y + w_{x, y} - dix_x >= 0\)
这样就构成了一个没有负数边权的图,我们可以以此来更新边权,
那么我们考虑新建一个源点连向每个点一个长度为 \(0\) 的边,然后跑一遍 SPFA 求出到每个点的最短路 \(dis_x\),然后对于每条边 \(u→v\),将其权值变为 \(w_{x,y}+dis[u]−dis[v]\) ,再从每个点跑 Dijkstra 即可。时间复杂度 \(O(nm+nm\log_n)\) 稀疏图吊打 Floyd。

浙公网安备 33010602011771号