题意:给定一个有向图,保证无重边自环,求将图中的每条边反向后强联通分量的个数是否会改变。
数据范围:$n$ $≤$ $1e3$,$m$ $≤$ $2e5$。
首先考虑一条边的影响。
因为一条边只能连接两个点,因此将一条边反向至多只能影响它两个端点在强联通分量里的变化,即整体增加一个强联通分量,或整体减少一个强联通分量(或整体不变)。
再考虑将这条边反向之前,两端点 $u$,$v$ 之间的联通情况。
假设这条边为 $u$ $→$ $v$,那么将这条边反向,在图中就可以看作增加一条 $v$ $→$ $u$ 的边,删掉一条 $u$ $→$ $v$ 的边。
那么在删边和添边之前,考虑 $4$ 种情况。
- 存在一条 $u$ $→$ $v$ 的路径,且其中不包含 $u$ $→$ $v$ 这条边;存在一条 $v$ $→$ $u$ 的路径;
- 存在一条 $u$ $→$ $v$ 的路径,且其中不包含 $u \to v$ 这条边;不存在一条 $v$ $→$ $u$ 的路径;
- 不存在不经过 $u$ $→$ $v$ 这条边的一条 $u$ $→$ $v$ 的路径 ;存在一条 $v$ $→$ $u$ 的路径;
- 不存在不经过 $u$ $→$ $v$ 这条边的一条 $u$ $→$ $v$ 的路径 ;不存在一条 $v$ $→$ $u$ 的路径;
稍加分析就能得出在整体增加一个强联通分量的时候,是情况 $2$;在整体减少一个强联通分量的时候,是情况 $3$。
原图中是否存在一条 $v \to u$ 的路径只需在原图中爆搜一遍即可。
考虑如何判断是否存在不经过 $u$ $→$ $v$ 这条边的一条 $u$ $→$ $v$ 的路径。
显然一个最暴力的思路就是枚举每条边,打个 $\text{tag}$ 后在图中爆搜,复杂度 $O(m^2)$。
这里复杂度爆炸的原因就是每条边的枚举,因为在图中爆搜是无法避免的,因此把枚举每条边改为枚举每个点 $a$ 试试。
$a$ 不走 $a \to b$ 这条边想要到达 $b$,只需要在不走环的情况下第一条边不走 $a \to b$ 这条边就行了,而若 $a$ 不走 $a \to b$ 这条边,那么相当于 $a$ 可以走除了 $b$ 以外的后继节点。
考虑将问题转化为 $a$ 的后继节点能够被 $a$ 的其他后继节点到达(在不在 $a$ 处走环的情况下,这个可以通过给 $a$ 打个标记等等办法特判)。
当然这个还是需要枚举 $a$ 的出边因此复杂度没有任何改进,进而考虑再将问题转化为 $a$ 的后继节点能够两两到达。
但是这个转化是不对等的,因为后者是前者的充分不必要条件,其实每个点只需要被另 $1$ 个点到达就行了。
这就转换为了一个点集中的点能否被其中的另一个点到达的问题,因此考虑用多源 $\text{bfs}$ 实现,但是因为环的缘故,每个点有可能自己到达自己,因此在被访问的时候要记录一下访问它的点集中的点是谁(这里需要记录两个),同时每个点可以两次入队。
不过由于本人常数过大的缘故,需要使用 $\text{bitset}$ 优化。
code:Submission #34083578 - AtCoder Regular Contest 092