[OI] 树上背包问题
1.[OI] 树上背包问题
2.[OI] 图论3.[OI] 关于最小环和负权环4.[OI] 分层图最短路5.[OI] 关于Eratosthenes筛法的优化思路6.[OI] DP7.[OI] 线段树8.[OI] 扫描线9.[OI] KMP10.[OI] 二分图11.[OI] 平衡树12.[OI] pb_ds13.[OI] Kruskal 重构树14.[OI] 模拟退火15.[OI] 可持久化数据结构16.[OI] Testlib17.[OI] 交互 | pipe18.[OI] 二项式期望 DP19.[OI] 整体二分20.[OI] 结构体引用类型转换21.[OI] 猫树22.[OI] 树链剖分23.Borůvka 算法24.线段树分治25.C++ 编译静态链接 (-static)树上背包问题的使用场景
当一个问题满足树的结构,而且需要让我们选取某些边或某些点,使权值取到最值。这样的问题是树上背包问题.
树上背包模板
树上背包问题使用dfs.
一般来说,树上背包问题的基本框架如下图:
void dfs(int s){
for(i:遍历s的全部子节点){
dfs(i);
for(j:背包容量倒序遍历(01背包问题时)){
for(k:0~j-1){
f[s][j]=max/min(f[s][j],f[i.to][k]+f[s][j-k-v[root]]+i.w);
}
}
}
}
可能有些难懂,下面来做些解释:
- 定义
为以 为根节点,背包容量为 时的最大权值. - 树上背包问题,依照背包问题的遍历方法,通常采用三层遍历,其中:第一层遍历全部子节点,第二层遍历背包容量.
- 树上背包问题中,一棵树的全部容量要分为根结点占用的容量和各个子树占用的容量,因此,第三层遍历当前子树占用当前树的容量.
- 注意第三层循环中
最小是 ,即一个都不分配,而最大值只能到 ,因为还要留一个分配给根节点. - 已知第三层遍历占用了
容量,权值在之前的dfs中已求出,应为 (这里 指子节点的根节点). 而根节点占用的容量为 , 权值为 . 所以,剩下没被占用的总容量为 ,其权值我们其实可以这样表示: (因为该值事先已求出),因此,得到状态转移方程为:
- 树上背包问题的边界条件是非常需要注意的,有时限制边界条件可以节省时间,或者避免越界.
- 建树时需要注意,该树需要是从父亲指向儿子的,否则无法快速找到子树.
- 在无法判断父子关系时,树也可以建成一个相同形状的无向图. 在遍历时加入一个记录该次遍历父节点的参数
并添加if(i.to==last) continue;
一句即可.
例题代码: 选课
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!