最短路

最短路算法拓展技巧

Floyd 传递闭包

有时候我们需要维护一些具有传递性的关系如相等连通等

初始条件往往是给定几组关系要把所有的关系求出来

可以把 Floyd 算法做一些调整

$$dis_{i,j}=dis_{i,j}~|~(dis_{i,k}~\&~dis_{k,j}) $$

时间复杂度还是 $\Theta(n ^ 3)$但由于位运算的特殊性有些时候可以使用 bitset 优化到 $\Theta\left(\frac{n ^ 3}{\omega}\right)$

Johnson 重赋权

对于多源最短路如果我们枚举一个点然后跑堆优化的 Dijkstra那么复杂度是 $\Theta(nm \log n)$在图比较稀疏的情况下这个复杂度要优于 Floyd 算法的 $\Theta(n ^ 3)$

但是 Dijkstra 算法要求所有边权均非负于是就有了重赋权的技巧

具体来说我们新建一个 $0$ 号点并且从这个点出发向所有点连一条边权为 $0$ 的边然后跑单源最短路(SPFA 或者 Bellman-Ford)设距离数组为 $h$ 接下来对于每条边 $(u, v)$

$$w^{\prime}(u, v)=w(u, v)+h(u)-h(v) $$

这样所有的边权都变成非负的我们就可以跑 Dijkstra 算法了

接下来证明这样做为什么是对的

首先由于 $h(v) \leqslant h(u)+w(u, v),$ 所以新图的边权一定非负

设新图上的最短路径为 $d^{\prime}$原图上的最短路径为 $d$

$$\begin{aligned}d^{\prime}(u, v) &= \min _{a_{1}, a_{2}, \ldots, a_{k}} w^{\prime}\left(u, a_{1}\right)+w^{\prime}\left(a_{1}, a_{2}\right)+\cdots+w^{\prime}\left(a_{k}, v\right) \\\\ &= \min _{a_{1}, a_{2}, \ldots, a_{k}} w\left(u, a_{1}\right)+\left(h(u)-h\left(a_{1}\right)\right)+w\left(a_{1}, a_{2}\right)+\left(h\left(a_{2}\right)-h\left(a_{1}\right)\right)+\cdots+w\left(a_{k}, v\right)+\left(h(v)-h\left(a_{k}\right)\right) \\\\ &= h(u)-h(v)+\min _{a_{1}, a_{2}, \ldots, a_{k}} w\left(u, a_{1}\right)+\cdots+w\left(a_{k}, v\right) \\\\ &= h(u)-h(v)+d(u, v)\end{aligned} $$

这个证明用到了势能分析的思想如果想进一步了解话可以参考本站杂项复杂度分析一文

最短路图

所谓最短路图就是在求完从 $S$ 出发的单源最短路之后只保留最短路上的边形成的有向图

只需要在求的过程中维护一个 $pre_u$ 数组表示点 $u$ 的前驱即可

很多最短路的变种都需要用这个算法有时候考虑最短路图也有利于发现一些隐藏的性质

经典例题

[LG1266] 速度限制

$dis_{i,j}$ 表示当前已经到 $i$上一个点是 $j$ 的时间最短路

本质上是个分层图最短路直接跑 Dijkstra 就好了

时间复杂度 $\Theta(nm\log n)$

[ICPC-BJ2006] 狼抓兔子

首先有定义

  • 平面图是指的存在某种方式使得图上所有边平铺在平面上无交
  • 对偶图是指的将平面图上的每个区域看作一个点两点连边当且仅当两区域相邻边权为将两区域分隔开的边的权值

有定理

平面图两点间最小割等于对偶图两点间最短路

于是在这道题中我们就可以将每个三角形区域看作一个点相邻区域连边后跑从左下角到右上角的最短路

时间复杂度 $\Theta(n^2\log n)$

[GXOI/GZOI2019] 旅行者

我们发现可以对 $k$ 个点二进制分组每次将 $k$ 个点分成两个集合 $S_1$$S_2$建一个源点 $s$ 向所有 $S_1$ 中的结点连长度为 $0$ 的边建一个汇点 $t$ 从所有 $S_2$ 中的结点开始向它连长度为 $0$的边求从 $s$$t$ 的最短路

可以发现若答案为两点 $x$$y$ 之间的最短路那么一定有 $x\not= y$这意味着它们至少在某一次二进制分组中被分到了不同的集合所以这样一定可以找到两点间的最短路

时间复杂度 $\Theta(Tn\log n\log k)$