Reading

IOI2019 景点划分


Fanyi Pu

给一张 n(3≤n≤105) 个点 m(2≤m≤2×105) 条边的无向连通图,以及三个正整数 a,b,c,保证 a+b+c=n。你需要对每个点染成三种颜色中的一种,使得这三种颜色的点的个数分别为 a,b,c,且有两种颜色的点构成两个联、连通块。可能无解。

我们先考虑我们这两个连通块的大小应该为多少。我们不妨令 a≤b≤c,那么我们发现其实只要让 a 和 b 是连通块即可。因为如果是 c 是连通块,那么我们显然可以通过删掉部分节点的方式将其的大小缩小。

考虑到这一点,如果这是一棵树的话,那算法就简单了。我们考虑枚举一条边,如果边两边的 size 分别大于了 a 和 b,那就 YES 了。如果找不到的话,那显然就是 NO。

然后我们考虑图的情况,其实就是在这棵树上加了几条边。考虑到我们考虑这棵树是这张无向图的 dfs 树,这样这些新加进去的边就一定是返祖边,而不会存在横叉边的情况。我们先忽略这条边,如果找到了一边大于 a 一边大于 b,那一定 YES。我们考虑找不到的情况,这时候我们就可以用那几条返祖边进行调整。一种比较直接的调整方法是,考虑 x 与 fx(x 父亲)的那条边,那我们可以将 x 子树中,存在返祖边为 x 祖先的那些子树加入到 fx 所在的那个集合中。也就是用减少 x 所在连通块大小的代价换取 fx 所在连通块大小的增加。让我们考虑对于一个 x,令 sx 表示节点 x 的大小。由于我们调整的目的是为了让 fx 所在连通块更大,所以我们考虑让 x 所在连通块不经过调整不能再小了,也就是 sx≥a 但对于 x 的任意一个儿子 t,都有 st<a。然后我们考虑进行调整。我们最终一定能找到一个临界,也就是不能继续调整了。这个时候有两种情况,第一种情况是,虽然还是有未加入 fx 所在连通块的存在与之有返祖边联通的子树 t,但如果加入该子树,那么 x 所在连通块大小就小于 a 了,考虑到此时 x 所在连通块大小为 u,子树 t 大小为 v,我们有 {u≥au−v<av<a,也即 a≤u<2a 那么我们考虑 fx 所在连通块的大小:n−u=a+b+c−u>a+b+c−2a=b+(c−a)≥b。也就是说这种情况一定是 YES 的。然后我们考虑第二种情况,就是已经没有子树有可用的返祖边了,那这时候如果 fx 所在连通块大小仍然小于 b 的话,那对于这个点,一定是不可能的了。那么,我们只要继续考虑其他的同样满足 sx≥a 且对于 x 的任意儿子 t 都有 st<a 的所有 x 即可。如果都不满足条件,那显然答案是 NO。这样复杂度 O(n)。

Cite this post

@misc{pu2021oiicpcotherproblemsioi2019split,
  author = {Pu, Fanyi},
  title  = {IOI2019 景点划分},
  year   = {2021},
  month  = {10},
  url    = {https://pufanyi.com/blog/oi-icpc/other-problems/ioi2019-split}
}