UOJ #661. 【IOI2021】keys

发布时间 2023-04-16 21:24:26作者: 275307894a

题面传送门

有点精妙的题目。

首先我们发现这个题目问的方式非常奇怪,它只要求最小的集合大小。这说明如果无脑把所有点的集合都求出来应该是做不了的。因此我们需要对于最小值的问题挖掘一点性质。

观察:如果 \(x\) 可以走到 \(y\) ,那么\(p_x\geq p_y\)。特别的,如果 \(y\) 可以走到 \(x\),那么有 \(p_x=p_y\)

这就启发我们对于某个点 \(x\),找到一个它可以走到的点 \(y\),那么要么 \(x\) 不会被算入最终答案,要么 \(x\) 可以被 \(y\) 走到。因此如果我们只保留 \(y\) ,最后再通过 \(y\) 搜出 \(x\) 对于答案是没有影响的。

那么我们就得到了一个过程:每次将仍然保留的点拿出来 BFS,如果搜到了自己联通块以外的点,那么就可以将这个点扔掉了。一次这个搜索的过程可以做到 \(O(n+m)\),但是会重复几次呢?

这和某个 B 开头的最小生成树算法非常像,只会重复 \(O(\log n)\) 轮,因为考虑当前的有用联通块个数 \(s\),这里的有用指的是仍然有可以走的边出去的点,其会产生 \(s\) 条边,即使考虑重边的情况下也会有 \(\frac{s}{2}\) 条边加入图中,会使有用的联通块数量减半。因此只有 \(O(\log n)\) 轮。总复杂度 \(O((n+m)\log n)\)

submission