2020牛客暑期多校训练营(第二场)C. Cover the Tree
链接
https://ac.nowcoder.com/acm/contest/5667/C
题意
在无根树中选择最少的链覆盖所有的边至少一次
思路
选择一个非叶子节点为根,按照 DFS 序记录下所有叶子
记 $l[i]$ 为按 DFS 序排序后排为 $i$ 的叶子节点,$cnt$ 为叶子个数
当 $cnt$ 为偶数,构造的链为 $l[i]\rightarrow l[cnt/2+1],l[i+1]->l[cnt/2+2],…,l[cnt/2]\rightarrow l[cnt]$
设某条边的儿子节点所覆盖的叶子节点的区间为 $[L,R]$
当 $R\le cnt/2$,这条边会被 $l[R]\rightarrow l[R+cnt/2]$ 覆盖
当 $L>cnt/2$,这条边会被 $l[L-cnt/2]\rightarrow l[L]$ 覆盖
否则因为根的度大于 $1$,所以 $L\ne 1$,$R\ne cnt$ 必有一个条件满足,若 $L\ne 1$,这条边会被 $l[1]\rightarrow l[cnt/2+1]$ 覆盖,若 $R\ne cnt$,这条边会被 $l[cnt/2]\rightarrow l[cnt]$ 覆盖
当 $cnt$ 为奇数,则给匹配剩下那个叶子节点随意匹配一个叶子节点即可
如果以一个叶子节点为根,将根加在按 DFS 序排序后的叶子节点的数组最后即可
代码
1 |
|