题目链接
题意
加工一棵有根树,一开始是竹竿(每个结点只有至多一个子结点的树),可以任意标号。设 $u$ 的父结点为 $p(u)$, 每次可以选一个非根点 $u$ 使得 $p(u)$ 也不是根,把 $p(u)$ 更改为 $p(p(u))$, 要求给出一种直链的标号和修改父边的方式,操作后得到指定的有根树。
题解
省队大佬Lagoon一眼就看出来了orz 他的想法:肯定是逐棵子树生产出来的,最后有一条链不用操作,那么一定取最长链,按照dfs序操作,使最长链上的点尽可能迟访问。
我把操作反过来,变成原树上可以把一个结点的父边改指向兄弟结点,大概是想到了可以把 $u$ 的子树给处理成 $u o v$ 的一条链,然后合并几棵树的时候在操作前把树串成一堆,然后依次成链,然后发现(操作次数+$v$ 的深度)这个量与 $v$ 无关。不过想了半个小时有余,还没时间写,差点掉分。
官方题解考虑反操作中树的高度,操作一次至多增加 $1$, 也可以通过构造做到恰好增加 $1$: 如果已经只剩一根竹竿,目标已经达成;否则找一条最长链,再找一条不在最长链上的边 $left<u, v ight>$, 把 $u$ 在最长链上的子结点(显然存在)的父边改指向 $v$, 树的高度就增加了 $1$.