树上问题学习笔记

前言:这篇博客是 yx NOIP 前恶补知识点写的,并没有普通树形 DP 捏/wq
upd:NOIP 没了,现在这里有普通树形 DP 了(

换根 DP

gg 押 NOIP 会考换根 DP,发现自己还没学过/jk
害怕.jpg

或许按本人感受的难度顺序排序(?

P3478 [POI2008] STA-Station

当根从 u 换到 v 时,v 的子树内所有节点深度 1,除此以外每个节点深度 +1。则转移方程为 fv=fusizv+(nsizv)

CF1187E Tree Painting

如果已知第一个选的点作为根节点,则最优选法肯定是从上往下依次选(好像也只能这样选(?)那这样选点 u 的得分就是 sizu,最后的答案是 irtsizi
于是就会发现换根的转移式子和上面那题是一样的。就做完了。

P2986 [USACO10MAR] Great Cow Gathering G

依旧同理,把 siz 换成子树内 ci 的和,转移柿子乘上边权 w 即可。

P3047 [USACO12FEB]Nearby Cows G

诈骗题。看到题想了半天怎么快速维护区间加减,然后发现自己眼瞎没看见 k20...
fi,j 表示以点 i 为根的子树里到 i 距离为 j 的所有点的权值和。
然后这东西 O(nk) 暴力转移就完了...
递归完要把修改过的值还原回来。

CF708C Centroids

终于有一道不一样的了
p.s.这题坑死我了。
先考虑已知根节点怎么判断合法性,那么就找到最大的子树,在这个子树里面找一个 x 使 sizusizxn2sizxn2
容易想到对于每个节点维护:sizx 子树大小,sonx 最大子树编号,fxx 为根的子树内不大于 n2 的最大子树大小(不包括 fx)。
然后你会发现这样没法 O(n) 换根 dp,因为当从 u 换到 vv 正好是 fu 那个节点的时候就寄了。
然而本喵并没有意识到,并且在这种情况下暴力枚举 u 的所有儿子来重新求 fu 甚至还以为它是 O(n),被菊花图成功卡 TLE/qd
于是思考并调了 1h 的代码白写了/fn
看了题解发现我们还要维护 fx 的次大值,并保证不是从同一个儿子转移过来。
这样上面那种情况就能直接取次大值来保证复杂度。
好麻烦/kk

P6419 [COCI2014-2015#1] Kamp

顺着上一题思路想出来了,但是要维护的东西好多啊/kk
肯定是需要一个 cntx 来判断子树内有无关键点的。(没有就不用往里走了)
首先思考怎么走是最优的方式。假设送完最后一个人要返回出发点的话,设 fx 为从点 x 出发走完所有关键点再回到 x 的最短路程。这个还是比较好求的,不详细写了(?
题意和上面 fx 的区别就在最后一个人送完不用回去。那肯定挑距离 x 最远的人当最后一个,因此要维护 disx,1/2 表示到 x 子树内关键点到 x 距离的最大/次大值。
然后因为距离一样的时候没法判断是不是同一个点,还要一起维护 gx,1/2 表示距离最值相对应的点的编号。
代码实现巨大多分讨,记得随时判断 cnt 是不是 0 以及 disu,1 是不是在子树 v 里。

其实还有两题要写的,但是摆了。记得抓我回来填坑。

树上背包

发现这个也不会。枯。希望现学来得及吧。

P2014 [CTSC1997] 选课

虽然以前写过,但似乎是没咋看懂式子稀里糊涂敲上去的(?
啊啊啊以前好多这种稀里糊涂照着题解思路/老师代码贺上去的题,每当提起我都记得做过,每当考到就发现不会,深受其害/ll

这题是个森林,则对每棵树的根节点向 0 连边,使之变成一棵树。
fi,j,k 表示子树 i 的前 j 个儿子,已经选了 k 门课的最大值。注意:必须选点 i
那么 fnow,tot,j=max(fnow,tot,j,fnow,tot1,jk+fv,mxtot,k)。同样注意 k 只能循环到 j1
类似背包进行滚动数组优化。(似乎滚动了反而更好写(?)
也不知道自己到底会没会/kk

P4516 [JSOI2018] 潜入行动

题面看起来还挺套路,但我不会,树形 dp 是真忘光了啊啊啊啊啊怎么办
式子好长不想写...算了口胡一下吧。
dp[u][j][0/1][0/1] 表示子树 u 里放了 j 个,点 u 放了/没放,是否已经被监听。
于是滚动数组一下推出长下面这样的转移柿子

{dp[x][i+j][0][0]=dp[x][i][0][0]×dp[v][j][0][1]dp[x][i+j][1][0]=dp[x][i][1][0]×(dp[v][j][0][0]+dp[v][j][0][1])dp[x][i+j][0][1]=(dp[x][i][0][1]×(dp[v][j][0][1]+dp[v][j][1][1])+dp[x][i][0][0]×dp[v][j][1][1])dp[x][i+j][1][1]=(dp[x][i][1][0]×(dp[v][j][1][0]+dp[v][j][1][1])+dp[x][i][1][1]×(dp[v][j][0][0]+dp[v][j][0][1]+dp[v][j][1][0]+dp[v][j][1][1]))

卡 long long 空间,要强制类型转换。
我不管,我胡了就是我写了!(确信

不知道啥题

OI wiki 为什么给我推黑题啊,不会/kk
所以写到这吧awa

树形 DP

范学长讲树上问题,顺路回来更新一波。

CF822F Madness

贪心题。胡了篇 lg 题解。

P2607 [ZJOI2008] 骑士

基环树上的 dp。第一次做这种题(?
对于每个基环树,dfs 找到环的那条边,对于这条边分别钦定 u 不选/v 不选,分别 dp 即可。
转移显然。
实现的时候写麻烦了,直接并查集判环就可以,不用 dfs。

posted @   樱雪喵  阅读(125)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示