关键观察:奇偶分层 BFS
图是无权图(每条边步数为 1),所以用 BFS 求最短路。
但这里不是"最短路 ≤L\leq L≤L"就行,而是要求恰好走 LLL 步。因为可以沿一条边来回走(浪费 2 步),所以:
> 如果从 aaa 到 1 的最短路是 ddd,且 ddd 和 LLL 奇偶性相同,且 d≤Ld \leq Ld≤L,则答案为 Yes。
原因:最短路走 ddd 步到达后,剩余 L−dL - dL−d 步是偶数,可以在任意一条边上来回走消耗掉。
但图中可能存在奇数环!如果存在经过节点 1 的奇数环,那么奇偶性可以切换。所以需要分别记录:
* diseven[v]dis_{even}[v]diseven [v]:从节点 1 出发,走偶数步到达 vvv 的最短步数
* disodd[v]dis_{odd}[v]disodd [v]:从节点 1 出发,走奇数步到达 vvv 的最短步数
对于查询 (a,L)(a, L)(a,L):
* 如果 LLL 是偶数:检查 diseven[a]≤Ldis_{even}[a] \leq Ldiseven [a]≤L
* 如果 LLL 是奇数:检查 disodd[a]≤Ldis_{odd}[a] \leq Ldisodd [a]≤L
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
实现方法:奇偶分层 BFS
把每个节点拆成两个状态 (v,0)(v, 0)(v,0) 和 (v,1)(v, 1)(v,1),分别表示走偶数步和奇数步到达 vvv。
从 (1,0)(1, 0)(1,0) 开始 BFS(走 0 步到达节点 1,0 是偶数)。
每走一条边,奇偶性翻转:(u,p)→(v,p⊕1)(u, p) \to (v, p \oplus 1)(u,p)→(v,p⊕1)。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
完整代码