Translation Notice
This article was machine-translated using DeepSeek-R1.
- Original Version: Authored in Chinese by myself
- Accuracy Advisory: Potential discrepancies may exist between translations
- Precedence: The Chinese text shall prevail in case of ambiguity
- Feedback: Technical suggestions regarding translation quality are welcomed
G - Typical Path Problem
Problem Statement
Given a simple undirected graph $G$ with $N$ vertices and $M$ edges, and three integers $A$, $B$, $C$.
Does there exist a simple path from vertex $A$ to $C$ that passes through $B$?
Constraints:
- $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$ are distinct)
What is a simple path?
A simple path does not visit the same vertex more than once. For example, $1\to 2\to 3$ is a simple path, but $1\to 2\to 1$ is not.
Solution 1: Maximum Flow
We observe that a simple path $A\to B\to C$ exists if and only if there are two paths $B\to A$ and $B\to C$ that share no vertices except $B$. This can be modeled as a maximum flow problem.
Construct a directed graph $G'$ with $(2N+2)$ vertices:
- Source: $s$
- Sink: $t$
- Entry points for each vertex in $G$: $x_1,\dots,x_N$
- Exit points for each vertex in $G$: $y_1,\dots,y_N$
Edges are added as follows:
- For each $1\le i\le N$, connect entry $x_i$ to exit $y_i$ with capacity $1$;
- Connect source $s$ to $x_B$ (entry of $B$) with capacity $2$;
- Connect exits $y_A$ and $y_C$ to sink $t$ with capacity $1$ each;
- For each original edge $(u,v)\in E_G$, connect $y_u \to x_v$ and $y_v \to x_u$ with capacity $1$.
Compute the maximum flow from $s$ to $t$. If the flow equals $2$, the required paths exist.
Proof
A flow of $2$ must utilize both $y_A\to t$ and $y_C\to t$ edges, implying existence of $B\to A$ and $B\to C$ paths. If these paths share any vertex $v$, both flows would require passing through the $x_v\to y_v$ edge (capacity $1$), making total flow $1$. Hence, a flow of $2$ guarantees vertex-disjoint paths.
Using Dinic’s algorithm, the time complexity is $\mathcal O(N+M)$ since the maximum flow is $2$.
Code Implementation
Notations:
- Source: $s=0$
- Sink: $t=2n+1$
- Entry of $i$: $x_i=i$
- Exit of $i$: $y_i=n+i$
AC Library Implementation
AtCoder Library provides a Dinic-based max flow implementation.
|
|
Manual Dinic Implementation
Dinic’s algorithm achieves $\mathcal O(N+M)$ complexity for this graph. For algorithm details, refer to OI Wiki.
Note on Memory Allocation
The transformed graph $G'$ contains $(N+2M+3)$ edges. Using static adjacency lists, allocate arrays of size $2(N+2M+3)$, which can safely be set to $1.25\times 10^6$.
|
|
Solution 2: Block Forest (Round-square Tree)
Correctness relies on:
- For any simple path $A\to C$, if $B$ lies in any biconnected component along this path, then $A\to B\to C$ exists. Otherwise, no such path exists.
Construct the block forest (round-square tree) using Tarjan’s algorithm:
- Build the block forest $T$ of $G$.
- Find the unique simple path $A\to C$ in $T$.
- Check if $B$ is adjacent to any square node (biconnected component) on this path.
Time complexity: $\mathcal O(N+M)$, with better practical performance than flow-based solutions.
Code Implementation
Tip: Allocate double-sized arrays for block forest nodes to avoid RE.
|
|
Comparison
Comparison of three solutions:
Solution | Code Length | Running Time | Memory Usage |
---|---|---|---|
Max Flow (AC Library)1 | $523~\mathrm{B}$ | $337~\mathrm{ms}$ | $106480~\mathrm{KB}$ |
Max Flow (Dinic)2 | $1650~\mathrm{B}$ | $334~\mathrm{ms}$ | $46980~\mathrm{KB}$ |
Block Forest3 | $1142~\mathrm{B}$ | $162~\mathrm{ms}$ | $57824~\mathrm{KB}$ |
The block forest solution has the fastest runtime. AC Library implementation offers the shortest code, while manual Dinic uses the least memory.
Personal Note
This problem is excellent—simple statement with rich underlying concepts.
I didn’t even think of using max flow during the contest