G - Typical Path Problem
题目大意
给定一张 $N$ 个点、$M$ 条边的简单无向图 $G$ 和三个整数 $A,B,C$。
是否存在一条从顶点 $A$ 到 $C$,且经过 $B$ 的简单路径?
数据范围:
- $3\le N\le 2\times 10^5$
- $N-1\le M\le \min(\frac{N(N-1)}2,2\times 10^5)$
- $1\le A,B,C\le N$($A,B,C$ 互不相同)
什么是 简单路径 ?
简单路径 是不重复经过同一个点的路径。例如,$1\to 2\to 3$ 是简单路径,但 $1\to 2\to 1$ 不是简单路径。
解法1:最大流
不难发现,存在一条 $A\to B\to C$ 的简单路径,当且仅当存在一条 $B\to A$ 和一条 $B\to C$ 的路径,使得这两条路径不经过同一个点($B$ 除外)。因此,我们可以构建网络流模型来解决此问题。
考虑由 $(2N+2)$ 个点组成的有向图 $G'$:
- 源点:$s$
- 汇点:$t$
- $G$ 中每个点对应的入点:$x_1,\dots,x_N$
- $G$ 中每个点对应的出点:$y_1,\dots,y_N$
然后进行连边:
- 对于每个 $1\le i\le N$,从入点 $x_i$ 向出点 $y_i$ 连接一条流量为 $1$ 的边;
- 从源点 $s$ 到中转点的入点 $x_B$ 连接一条流量为 $2$ 的边;
- 从 $A$ 和 $C$ 的出点 $y_A,y_C$ 向汇点 $t$ 分别连接一条流量为 $1$ 的边;
- 最后,$\forall (u,v)\in E_G$,连接 $y_u \to x_v$ 和 $y_v \to x_u$,流量为 $1$。
计算 $s$ 到 $t$ 的最大流,如果最大流为 $2$ 则必定有存在不经过同一个顶点的 $B\to A,B\to C$ 的路径。
证明
显然,如果最大流为 $2$,必然通过了 $y_A$ 和 $y_C$ 向汇点连接的边,则一定分别有 $B\to A$ 和 $B\to C$ 的路径。
假设选择的这两条路径经过了同一顶点 $v$,则两流都必须经过 $x_v\to y_v$ 这一条流量为 $1$ 的边,此时最大流不可能超过 $1$。而最大流为 $2$,说明假设不成立,故没有经过同一顶点。
若使用 $\text{Dinic}$ 算法,由于最大流不超过 $2$,网络流的时间复杂度为 $\mathcal O(N+M)$。
代码实现
在以下的两种实现中,我们规定
- 源点:$s=0$
- 汇点:$t=2n+1$
- $i$ 的入点:$x_i=i$
- $i$ 的出点:$y_i=n+i$
AC Library 实现
AtCoder Library 内置最大流的 $\text{Dinic}$ 实现。
|
|
Dinic 手写实现
$\text{Dinic}$ 算法对于此图的时间复杂度为 $\mathcal O(N+M)$。如果不清楚算法原理可以参考 OI Wiki。
关于空间分配问题
由于新图 $G'$ 包含 $(N+2M+3)$ 条边,若使用静态链式前向星存图,数组大小需要开到 $2(N+2M+3)$,其理论最大值为 $1.2\times 10^6+6$。此处建议使用 $1.25\times 10^6$ 大小的数组。
|
|
解法2:圆方树
注意到以下算法的正确性:
- 找到 $A\to C$ 的任意简单路径。对于经过的每一个点双连通分量,如果 $B$ 在此点双内,则必然存在 $A\to B\to C$ 的简单路径;如果 $B$ 不属于任一经过的点双,则不可能存在 $A\to B\to C$ 的简单路径。
因此,可以使用 $\text{Tarjan}$ 算法构造原图的圆方树 $T$ 来解决此问题。将上述算法转换到圆方树上如下:
- 在 $T$ 上找到 $A\to C$ 的唯一简单路径。对于经过的每一个方点,如果 $B$ 是与其相邻的圆点,则必然存在 $A\to B\to C$ 的简单路径;如果 $B$ 不与任一经过的方点相邻,则不可能存在 $A\to B\to C$ 的简单路径。
总时间复杂度为 $\mathcal O(N+M)$,实际运行时间优于网络流解法。
代码实现
小贴士:圆方树相关的数组要开到两倍大小,不然会 RE 哦~
|
|
总结
三种解法的对比参见下表:
解法 | 代码长度 | 运行时间 | 内存占用 |
---|---|---|---|
最大流(AC Library)1 | $523~\mathrm{B}$ | $337~\mathrm{ms}$ | $106480~\mathrm{KB}$ |
最大流(Dinic)2 | $1650~\mathrm{B}$ | $334~\mathrm{ms}$ | $46980~\mathrm{KB}$ |
圆方树3 | $1142~\mathrm{B}$ | $162~\mathrm{ms}$ | $57824~\mathrm{KB}$ |
可见,圆方树算法的运行速度最快,最大流(AC Library)的代码最短,最大流(Dinic)的内存占用最小。
个人评价
这道题出得很好,题意简单而内涵丰富。
我赛时甚至没想到还可以网络流