【题解】Solution Set - NOIP2024集训Day28 树形 dp
【题解】Solution Set - NOIP2024集训Day28 树形 dp
https://www.becoder.com.cn/contest/5521
「HDU4661」Message Passing
一个合法方案的构成一定是:
- 先将所有的信息整合到一个点上;
- 然后从这个点扩展开。
「BZOJ3935」Rbtree
「ARC101E」Ribbons on Tree
「AGC034E」Complete Compress
假如我们现在已经知道了最后会合的那个点 \(x\)。
以她为根,根节点 \(dep_x=0\)。如果我们能找到一种合适的匹配方式,那么答案就应该是 \(\sum dep_i/2\),否则应该无解。
现在就变成了一个判断问题。考虑 dp。
\(f_{i}\):在 \(i\) 这棵子树内,尽可能配对完(配对的都到 \(i\))之后剩下最少的到 \(i\) 的距离之和。
\(h_i\):在 \(i\) 这棵子树内,棋子个数。
如果 \(f_x=0\) 那么就可以更新答案。
一个子儿子的子树需要上移的次数为 \(g_v=f_v+h_v\)。
我们记录一个点的所有儿子的 \(g\) 之和 \(sum\),\(g\) 的最大值 \(mx\)。
如果 \(mx\times2>sum\),就是说必须要向上有 \(mx-(sum-mx)\)。
否则就可以 \(f_u=sum\bmod 2\)。
但是:WA 90pts
问题在于这个 dp 其实是带有了一定的贪心,相当于我们是算了每个子树内都要尽量匹配,但是有这种情况:
对于 \(4,5,6\) 节点的 \(f\) 分别为 \(2,2,4\)。
对于 \(1\) 点显然是合法的,但是这个做法让 \(4,5\) 节点在 \(2\) 就合并了,也就是说 \(f_2=0\),导致 \(6\) 上的不能到 \(1\)。
其实我们需要的并不是每个儿子都最优,而需要的是每个儿子尽量的均衡。
\(f\) 记录了每个子树需要的最小值,我们不妨记录需要的最大值 \(g\),也即所有点到当前根的距离之和。
在这个范围内的,每隔两个值都能取到其中一个。
所以上面求的 \(sum\) 实际上是下界,但是我们需要的其实是上界,然后再按上面的做法做就行。
「COCI 2014.10」Kamp
答案就是所有经过的边的并集的权值和 \(\times~ 2~-\) 距离当前点最远的点。
有点恶心的换根 dp。bf
需要记录次长链,因为不要求严格,所以没必要记录最长链是指向哪个儿子,直接判值相等就行。
「SCOI2015」小凸玩密室
做过。
一种状态的定义:
\(f_{u,x}\): 走完 \(u\) 的子树,结束在 \(x\)(\(u\) 子树中的叶节点)。
这样可以 \(O(n^3)\) 解决。
但实际上不管最终在那个点结束,都会跳到 \(u\) 的祖先或祖先的兄弟,所以换一种定义:
\(f_{u,x}\): 走完 \(u\) 的子树,结束在 \(u\) 的第 \(x\) 级祖先的兄弟。
\(g_{u,x}\): 走完 \(u\) 的子树,结束在 \(u\) 的第 \(x\) 级祖先。
注意到对于一条路径我们把其拆分开算的(只要终点一样。