题目链接:Luogu P5058 [ZJOI2004] 嗅探器
题目描述:
给定一张无向图,以及两个点
s,t
,你需要找到一个点(这个点不能是s
或t
),这个点被所有s,t
之间的路径所经过。如果不存在这样的点,输出No solution
。如果有多个这样的点,输出编号最小的。
题解:
我们很容易发现要删除的点一定是割点(按照题意,删除后,
s
与t
不能进行通信,这说明强连通分量增加了)。我们只需要考虑哪些割点是满足条件的。如果我们以s
作为根结点进行Tarjan
,对于一个割点u
(非s
或t
),我们不难发现t
一定不能是之前遍历过的点(如果是之前遍历过的点,那么删除u
后,s
和t
依然可以到达)也就是必须满足dfn[u] < dfn[t]
,同时如果删除u
,那么对于其所有满足low[v]>=dfn[u]
的儿子结点v
均会产生一个新的强连通分量,如果t
在这些新产生的联通分量中的某一个,那么u
明显是满足条件的(删除u
后,t
将与s
不可达),t
在这些联通分量中的一个也就是t
是某个v
结点或者在v
的子树中,即满足dfn[t] >= dfn[v]
。不难发现如果满足dfn[t] >= dfn[v]
那么dfn[t] > dfn[u]
一定是成立的,因此只需要判断非s
或t
的割点是否存在某个儿子v
满足dfn[v]<=dfn[t]
即可。
代码:LuoguP5058