CF923F 题解
blog。好帅的题!!!但是写了 5k,写加调用了三个小时 /tuu
突破口是菊花。显然,若存在一棵树是菊花,则无解。其他情况呢?
考虑菊花再外挂一个叶子的情况。记这棵树为 \(T\),令一棵为 \(T^{\prime}\)。设这个外挂的叶子是 \(x\),其邻居为 \(v\),菊花中心为 \(u\)。只能将 \(u\) 对应到 \(T^{\prime}\) 上的一个叶子 \(u^{\prime}\),同时考虑钦定 \(u^{\prime}\) 在 \(T^{\prime}\) 上的邻居为 \(x^{\prime}\),以及随意钦定一个 \(T^{\prime}\) 上不与 \(u^{\prime},x^{\prime}\) 相邻的点为 \(v^{\prime}\)。映射 \(\{u\to u^{\prime},v\to v^{\prime},w\to w^{\prime}\}\),其他点乱放。画画图,发现显然是对的。
考虑菊花再外挂两个叶子的情况。考虑在 \(T\) 上先暂时删除两个叶子 \(u,v\) 满足两点没有公共邻居,同时在 \(T^{\prime}\) 上也随意删除两个没有公共邻居的叶子 \(u^{\prime},v^{\prime}\)。删完后的 \(T\) 不可能是菊花,于是其必然是 "菊花再外挂一个叶子的情况"。同上映射掉剩余的 \(n-2\) 个节点。然后分别尝试 \(\{u\to u^{\prime},v\to v^{\prime}\},\{u\to v^{\prime},v\to u^{\prime}\}\),由于保证了 \(u,v\) 两点没有公共邻居,画画图不难发现,两者必有一种可以成功映射。
考虑任意树。发现与外挂两个叶子的情况没有本质区别,只是需要归纳构造很多次罢了。于是就做完了。
不难发现,上述做法在 \(N\) 较小时会出问题。递归到 \(N\) 小时暴力求解即可。
复杂度可以用 set 精细实现做到 \(O(N\log N)\)。不过真的写起来非常大便,而良心出题人允许小常数 \(O(N^2)\) 通过,所以代码写成平方暴力了也没有关系。毕竟这个题时间复杂度又不是重点(
这个题相当难写。提供一点实现上的帮助:
- 这里是简易 Special Judge 与简易 Datamaker!!!
- 特判到 \(N\le5\) 就够了。
- 特判掉 \(N\) 较小的情况后,菊花中心满足 \(|G_u|=n-1\),外挂菊花的中心满足 \(|G_u|=n-2\)。
- 可以写成
std::vector
传剩余编号的形式,只要空间别爆就行。 - 处理第二棵树是 "菊花再外挂一个叶子的情况" 时,往答案数组里面记得反过来丢。
- 找外挂叶子可以直接以菊花中心为根,找到唯一的 \(dep_i=3\) 的点。
- 如何找 "两个没有公共邻居的叶子":注意到此时图不会是菊花,因此随便选一个叶子,总是会有另一个符合要求的叶子,否则图就变成菊花了。
code,我写的是平方。