「清华集训 2017」小 Y 和二叉树
「清华集训 2017」小 Y 和二叉树
原题数据好像没有卡这个情况
1 | 5 |
输出是
1 | 1 2 3 4 5 |
首先考虑一个$O(n^2)$的暴力:
枚举一个点为根,向下展开树,此时只需要决策左儿子和右儿子的顺序
当两个子树都存在时,由于两个子树包含的元素不同,所以可以直接把 两个子树序列首较小 (显然不会出现相同的情况) 的一个放在前面即可
实际上我们可以发现,这样得到的序列第一个元素必然是 编号最小的 、不同时包含左右儿子 的结点
不妨称固定根之后,这样的结点为叶子
显然的性质:任何一个度数$\leq 2$的点可以作为答案序列的第一个点
设原树上最小的$\leq 2$的点为$root$,接下来对于$root$的不同情况讨论,要在强制$root$为序列首的情况下,求得最小的序列
不妨先预处理出结点$u$子树里最小的叶子$mi_u$
1.没有相邻结点,结束
2.有两个相邻结点,此时要使自己为序列首,必然有一个结点是自己的父亲,有一个结点是自己的右儿子
右儿子会被先遍历到,所以可以直接考虑比较两个相邻结点 作为 右儿子时谁的序列首 较小
即比较两个子树中最小的叶子即可
3.只有一个相邻结点,设其为$v$
此时要使得自己为序列第一个,只有两种可能,此时同样可以考虑比较序列首元素
3-1.让相邻结点作为自己的父亲,此时下一个元素一定是$v$
3-2.让相邻结点作为自己的右儿子,此时下一个元素一定是$mi_v$
如果$v\ne mi_v$,显然好决策
当$v=mi_v$时,必然满足$v$是一个叶子,此时如果将$v$放在父亲上,$v$的另一个相邻结点(如果存在)
可以放在$v$的父亲或者是$v$的右子树,如果放在$v$的右子树,那么这种情况与$v$被放在$u$的子树等价
也就是说,把$v$放在父亲可以决策出的序列情况,包含了把$v$放在右儿子的情况
所以这种情况也应当把$v$放在父亲上
实现上,不妨用两个$dfs$处理最后的决策,一个强制当前结点$u$为序列首,一个求出$u$子树的最优方案
在代码里就是$Solve,dfs_get$
1 |
|