创世纪
算法
观察到把每个 \(a_i\) 向 \(i\) 连边, 形成一个外向基环树森林
问题转化为
在一个基环树上, 选择一个点后, 其儿子节点至少有一个不能选, 求最大选点个数
对于森林中的每一棵基环树
容易想到找环, 对于环上每一点, 问题转化为树上的上述问题
显然是树形 dp
令 \(f_{x, 0 / 1}\) 表示以点 \(x\) 为根节点, 是否选择 \(x\) , 其子树中最大选点个数
有
\[\left\{
\begin{array}{lr}
f_{x, 0} \gets \sum \mathop{\max}\limits_{y \in \rm{son}(x)} \left(f_{y, 0}, f_{y, 1}\right)& \\
f_{x, 1} \gets \mathop{\max}\limits_{y \in \rm{son}(x)}{\left[f_{x, 0}− \max{\left(f_{y, 0}, f_{y, 1}\right)}+f_{y, 0} + 1\right]} = \mathop{\max}\limits_{y \in \rm{son}(x)}{\{ f_{x, 0}− \left[\max{\left(f_{y, 0}, f_{y, 1}\right)} - f_{y, 0}\right] + 1 \} } & \\
\end{array}
\right.
\]
这是好求的
环上处理
环上有 \(N\) 个点, 每个点有贡献 \(W_i = f_i\) , 求选点最大贡献和, 其中, 不能选择相邻的点
令 \(dp_i\) 表示考虑到 \(i\) 点的最大贡献
钦定第一个必选, 按链的方式做一次
\[dp_{i \in [3, N - 1]} \gets \left( \max_{j \in [1, i - 2]} dp_j \right) + W_i
\]
再钦定第一个不选, 按链的方式做一次
\[dp_{i \in [2, N]} \gets \left( \max_{j \in [1, i - 2]} dp_j \right) + W_i
\]
断环处理
断掉环上一条边, 基环树变成一棵树
考虑解决掉删除这一条边的问题
- 使用这一条边
- 不使用这条边
代码
略
总结
基环树 + 常见树上 dp + 环上 dp
基环树一般都是一大堆 树上 / 图上知识串起来
这个树形 dp 算比较典的, 但我最初推出来的还是错的
注意消除删边影响这一类题, 通常是跑两次
内向树不好处理, 考虑建反向边
注意内外向树的判定

浙公网安备 33010602011771号