二叉苹果树 - 二叉树树型DP
传送门
中文题面:
题目描述
有一棵苹果树,如果树枝有分叉,一定是分 2 叉(就是说没有只有 1 个儿子的结点,这棵树共有N 个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有 4 个树枝的树:
2 5
\ /
3 4
\ /
1
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
输入格式
第1行2个数,N 和Q(1<=Q<= N,1<N<=100)。N 表示树的结点数,Q 表示要保留的树枝数量。
接下来 N-1 行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号,第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。
输出格式
一个数,最多能留住的苹果的数量。
样例数据 1
输入
5 2
1 3 1
1 4 10
2 3 20
3 5 20
输出
21
题目分析
此题是选课的简化版,因为规定了树是一颗二叉树,dp[i][j]表示以i为根节点的子树选择j条边的最大值,因为是棵树,所以可以将边权转移到点权上,剩下的就与选课一题异曲同工。
若选择当前节点:
- 此节点是根节点的话,左右儿子一共分担j个。枚举即可。
- 此节点不是根节点,左右儿子一共分担j-1个。
若不选择当前节点:dp = 0。
取较优值。
code
#include<bits/stdc++.h>
using namespace std;
const int N = 100;
int ecnt, adj[N + 5], go[N * 2 + 5], nxt[N * 2 + 5], val[N + 5], len[N * 2 + 5];
int fa[N + 5], ch[N + 5][2];
typedef long long ll;
ll dp[N + 5][N + 5];
int n, m;
inline void addEdge(int u, int v, int c){
nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v, len[ecnt] = c;
nxt[++ecnt] = adj[v], adj[v] = ecnt, go[ecnt] = u, len[ecnt] = c;
}
inline void dfs(int u, int f){
fa[u] = f;
int cnt = -1;
for(int e = adj[u]; e; e = nxt[e]){
int v = go[e];
if(v == f) continue;
ch[u][++cnt] = v;
val[v] = len[e];
dfs(v, u);
}
}
inline ll DP(int u, int k){
if(u == 0) return dp[u][k] = 0;
if(dp[u][k] != -1) return dp[u][k];
dp[u][k] = 0;
//选择这个
for(int i = 0; i <= k - 1 + (u == 1 ? 1 : 0); i++){
DP(ch[u][0], i);
DP(ch[u][1], k - 1 + (u == 1 ? 1 : 0) - i);
dp[u][k] = max(dp[u][k], 1LL * val[u] + dp[ch[u][0]][i] + dp[ch[u][1]][k - 1 + (u == 1 ? 1 : 0) - i]);
}
return dp[u][k];
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
cin >> n >> m;
for(int i = 1; i < n; i++){
int x, y, c;
cin >> x >> y >> c;
addEdge(x, y, c);
}
dfs(1, 0);
// for(int i = 1; i <= n; i++) cout<<i<<": "<<fa[i]<<" "<<ch[i][0]<<" "<<ch[i][1]<<" "<<val[i]<<endl;
memset(dp, -1, sizeof dp);
DP(1, m);
cout << dp[1][m] << endl;
return 0;
}
二叉苹果树 - 二叉树树型DP的更多相关文章
- 洛谷P2015 二叉苹果树(树状dp)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 【P2015】二叉苹果树(树状DP)
蒟蒻弱弱的开始做树形DP了,虽然做了这道题还是有很多不懂得地方. 这道题大意就是有一棵树,只保留其中q条边,求出剩余边的最大权值. 然后开始考虑怎么做(其实是看着题解出思路....),很容易可以想出D ...
- 二叉苹果树|codevs5565|luoguP2015|树形DP|Elena
二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的 ...
- BZOJ 1864 三色二叉树 - 树型dp
传送门 题目大意: 给一颗二叉树染色红绿蓝,父亲和儿子颜色必须不同,两个儿子颜色必须不同,问最多和最少能染多少个绿色的. 题目分析: 裸的树型dp:\(dp[u][col][type]\)表示u节点染 ...
- 刷题总结——二叉苹果树(ssoj树形dp+记忆化搜索)
题目: 题目背景 URAL:http://acm.timus.ru/problem.aspx?space=1&num=1018 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 2 叉(就是说 ...
- CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)
CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...
- P2015 二叉苹果树,树形dp
P2015 二叉苹果树 题目大意:有一棵二叉树性质的苹果树,每一根树枝上都有着一些苹果,现在要去掉一些树枝,只留下q根树枝,要求保留最多的苹果数(去掉树枝后不一定是二叉树) 思路:一开始就很直接的想到 ...
- [Luogu2015]二叉苹果树(树形dp)
[Luogu2015] 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. ...
- [树形DP]二叉苹果树
二 叉 苹 果 树 二叉苹果树 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定 ...
随机推荐
- Appium_Java运行测试脚本时问题汇总
问题一.java.lang.NoClassDefFoundError: org/openqa/selenium/remote/SessionNotFoundExceptionCaused by: ja ...
- c编程:僵尸吃大脑
第一行输入一个正整数n 以下每一行输入僵尸已经吃了的大脑数量a,和需要生存必需要吃的大脑数量b.总共n行. 例子输入 3 4 5 3 3 4 3 例子输出 NO BRAINS MMM BRAINS M ...
- Android 监听电量的状态
监控手机电量的变化和充电状态 在BatteryManager中有一个粘性广播,不需要BroadcastReceiver作为接收器,在注册时将传入null IntentFilter filter = n ...
- Dcloud课程5 php如何实现文件缓存技术(静态数据缓存)
Dcloud课程5 php如何实现文件缓存技术(静态数据缓存) 一.总结 一句话总结:保存在磁盘上的静态文件,用PHP生成数据到静态文件中.其实cookie和session使用的就是这样的技术,所以c ...
- php课程 11-37 类和对象的关系是什么
php课程 11-37 类和对象的关系是什么 一.总结 一句话总结:类生成对象,对象是类的实例化,一定是先有类,后有对象,一定是先有标准,再有个体. 1.oop的三大优势是什么? 重用性,灵活性.扩展 ...
- UVA 11136 - Hoax or what (可以提交了,不会Submission error了)
看题传送门:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- HDU 1997汉诺塔VII
又是汉诺塔~ 回顾一下汉诺塔的移动过程. 从左到右设为A,B,C 3个盘子的时候 1: No.1 A -> C 2: No.2 A -> B 3: No.1 C -> B 4 ...
- 3、在编译过程中出现no space left on device
原因:通过df -h查看发现磁盘空间不错 删掉不需要的文件后执行sudo apt-get clean
- Win10系统如何设置所有程序默认以管理员身份运行?
原文:Win10系统如何设置所有程序默认以管理员身份运行? 在win10系统中有些用户发现一些程序只有使用管理员身份运行能才打开,这样的话就感觉会麻烦很多,那么有没有办法设置所有程序都默认以管理员身份 ...
- cocos 关于文件名称的各种坑 各种斜杠坑
cocos 全部文件路径 的斜杠 必须 用 / 而不能够用 \ 不然编译到安卓各种坑 相对路径 第一个字符不可 带 / /*比如 res/test.png 这样的应该是标准的 /res/test.p ...