二叉苹果树
根固定为1的二叉树,保留恰好Q条边,使保留边
正文
/*
原题:二叉苹果树(一本通 5.2 例1)
题意:根固定为 1 的二叉树,保留恰好 Q 条边,使保留边上的苹果总和最大。
思路:树形背包 dp[u][j] 表示 u 子树内选 j 条边的最大苹果;合并儿子时选其分支需占用连边 u-v。根答案为 dp[1][Q]。
复杂度:O(N*Q^2) 时间,O(N*Q) 空间。
易错点:边权在连边上,选儿子分支要算上 u-v 这条边;根不计入连父边。
*/
#include <bits/stdc++.h>
using namespace std;
const int N=105;
int n,q;
vector<pair<int,int>> g[N];
int dp[N][N];
int sz[N];
void dfs(int u,int fa){
sz[u]=0;
for(int j=0;j<=q;j++)dp[u][j]=0;
for(auto&e:g[u]){
int v=e.first,w=e.second;
if(v==fa)continue;
dfs(v,u);
sz[u]+=sz[v]+1;
for(int j=min(q,sz[u]);j>=1;j--){
for(int k=1;k<=sz[v]+1&&k<=j;k++){
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k-1]+w);
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>q;
for(int i=1;i<n;i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back({v,w});
g[v].push_back({u,w});
}
dfs(1,0);
cout<<dp[1][q]<<"\n";
return 0;
}
一本通·提高篇的其它内容
- 活动安排
- 种树
- 喷水装置
- 加工生产调度
- 智力大冲浪
- 数列极差
- 数列分段
- 线段
- 家庭作业
- 钓鱼
- 糖果传递
- 愤怒的牛
- Best Cow Fences
- 曲线
- 数列分段 II
- 扩散
- 灯泡
- 传送带
- 数的划分
- 生日蛋糕
- 小木棍
- Addition Chains
- 埃及分数
- 平板涂色
- 质数方阵
- 靶形数独
- 电路维修
- 魔板
- Knight Moves
- 棋盘游戏
- Keyboarding
- 移动玩具
- 山峰和山谷
- Oulipo
- 图书管理
- Power Strings
- Seekthe Name, Seek the Fame
- Friends
- A Horrible Poem
- Beads
- Antisymmetry
- 门票
- 收集雪花
- 剪花布条
- Power Strings
- Radio Transmission
- OKR-Periods of Words
- 似乎在梦中见过的样子
- Censoring
- Phone List
- The XOR Largest Pair
- Nikitosh 和异或
- Immediate Decodability
- L 语言
- Secret Message 秘密信息
- 背单词
- The Xor-longest Path
- Keywords Search
- 玄武密码
- Censoring