Loading

创世纪

算法

观察到把每个 \(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 算比较典的, 但我最初推出来的还是错的
​注意消除删边影响这一类题, 通常是跑两次
内向树不好处理, 考虑建反向边

注意内外向树的判定

posted @ 2024-11-08 19:44  Yorg  阅读(11)  评论(0)    收藏  举报