树形DP
trick
题目
CF1276D Tree Elimination
题目大意
T1
给定一棵树,边按输入顺序依次处理。对每条边,若其两端点都未被删除,则选择其中一个删除并将其编号加入序列;否则跳过。求最终能得到的所有不同序列数量。
\(n \le 2\times 10^6\)。
解题思路
解题思路
有一些简单的小性质,到时候分析可能会有所帮助:
-
相邻两个点不可能同时不删。
-
每个点删还是不删是有他周围的点的选取情况决定的。
我们发现,每个子树其实内部顺序是独立的,因此,我们可以考虑使用树形 DP,定义 \(f_{u,0/1/2/3}\) 表示该节点被父边之前的子边删、被父边删、被父边之后的子边删、不删。
先考虑被子边删的情况 \(f_{u,0/2}\),具体是哪个还要看当前枚举的子边在不在父边之前,有以下转移:
考虑当前通过边 \((u,v)\) 来删掉 \(u\),那么它由 \(f_{v,2,3}\) 转移过来,同时还要考虑之前的还有之后的 \(son_u\) 的贡献,之前的必须删,之后的可以也可以不删,式子:
\[f_{u,0/2}\gets^{+} f_{v,2/3}\times \prod_{w<v,w\in son_u} f_{w,0/1}\times \prod_{w>v,w\in son_u} f_{w,0/2/3}
\]
对于 \(f_{u,1},f_{u,3}\) 显然有
\[f_{u,1}\gets^{\times} \prod_{v<fa,v\in son_u} f_{v,0/1}\times \prod_{v>fa,w\in son_u} f_{v,0/2/3}\\
f_{u,3}\gets \prod_{v\in son_u} f_{v,0/1}
\]
在树形 DP 过程中动态维护即可,复杂度 \(O(n)\)。

浙公网安备 33010602011771号