洛谷 P2015 二叉苹果树
老规矩,先放题面
题目描述
有一棵苹果树,如果树枝有分叉,一定是分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个。输出格式:
一个数,最多能留住的苹果的数量。输入输出样例
输入样例:
5 2
1 3 1
1 4 10
2 3 20
3 5 20输出样例:
21
题意中有隐含条件,要仔细读题,如果要选择当前边的话,那么也必须它与根节点的连线上的边也必须全部选中
动态转移方程:\(f[u][j]=max(f[u][j],f[u][j-k-1]+f[v][k]+e[i].w)(1≤j≤min(q,b[u]),0≤k≤min(b[v],j-1))\)
\(u\)表示当前节点,\(v\)为他的一颗子节点,\(b\)数组表示以i为根节点树上的边数
看到这里,相信方程大家很容易就能看明白甚至自己就能想明白,但是范围为什么是这样的呢?
我们着重讲一下这个取值范围的问题
首先先看\(k\),\(k\)在此处表示取\(v\)子树上的边数,最大自然不能超过\(b[v]\)但是为什么要小于等于\(j-1\)而不是\(j\)呢?
我们前面提到过了,题目中是有隐含条件的,若要选取子树\(v\)上的边,则必须选取\(u\)与\(v\)相连的边保证选取的边全部与根节点相连
然后就是\(j\),\(b[u]\)数组是在实时发生变化的,它不断加上自己子树的边,保证背包容量不断扩大,此处千万不要写成\(b[v]\)
下放代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define maxn 105
#define gc() getchar()
#define ll long long
using namespace std;
inline ll read(){
ll a=0;char p=gc();int f=0;
while(!isdigit(p)){f|=(p=='-');p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}
struct ahaha{
int to,next,w;
}e[maxn<<1];
int n,q,head[maxn],f[maxn][maxn],b[maxn],sz;
inline void add(int u,int v,int z){
e[sz].to=v;e[sz].w=z;e[sz].next=head[u];head[u]=sz++;
}
void dfs(int u,int fa){
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;if(v==fa)continue; //防止死循环
dfs(v,u);
b[u]+=b[v]+1; //当前点的边数加上子树的边数后,还需加上与子树相连的那一条边
for(int j=min(q,b[u]);j>=1;--j)
for(int k=min(b[v],j-1);k>=0;--k)
f[u][j]=max(f[u][j],f[u][j-k-1]+f[v][k]+e[i].w);
}
}
int main(){memset(head,-1,sizeof head);
n=read();q=read();
for(int i=1;i<n;++i){
int x=read(),y=read(),z=read();
add(x,y,z);add(y,x,z); //由于是树,每条边我们添加两遍,便于使用
}
dfs(1,0);
printf("%d",f[1][q]);
return 0;
}
洛谷 P2015 二叉苹果树的更多相关文章
- 洛谷 P2015 二叉苹果树 (树上背包)
洛谷 P2015 二叉苹果树 (树上背包) 一道树形DP,本来因为是二叉,其实不需要用树上背包来干(其实即使是多叉也可以多叉转二叉),但是最近都刷树上背包的题,所以用了树上背包. 首先,定义状态\(d ...
- 洛谷p2015二叉苹果树&yzoj1856多叉苹果树题解
二叉 多叉 有一棵苹果树,如果树枝有分叉,可以是分多叉,分叉数k>=0(就是说儿子的结点数大于等于0)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1~N,树根编号一定是1.我们用一根树枝两 ...
- 洛谷 P2015 二叉苹果树(codevs5565) 树形dp入门
dp这一方面的题我都不是很会,所以来练(xue)习(xi),大概把这题弄懂了. 树形dp就是在原本线性上dp改成了在 '树' 这个数据结构上dp. 一般来说,树形dp利用dfs在回溯时进行更新,使用儿 ...
- 洛谷 P2015 二叉苹果树 && caioj1107 树形动态规划(TreeDP)2:二叉苹果树
这道题一开始是按照caioj上面的方法写的 (1)存储二叉树用结构体,记录左儿子和右儿子 (2)把边上的权值转化到点上,离根远的点上 (3)用记忆化搜索,枚举左右节点分别有多少个点,去递归 这种写法有 ...
- 洛谷P2015 二叉苹果树
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 洛谷—— P2015 二叉苹果树
https://www.luogu.org/problem/show?pid=2015 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点 ...
- 洛谷P2015 二叉苹果树(树状dp)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 洛谷P2015二叉苹果树
传送门啦 树形 $ dp $ 入门题,学树形 $ dp $ 的话,可以考虑先做这个题. $ f[i][j] $ 表示在 $ i $ 这棵子树中选 $ j $ 个苹果的最大价值. include #in ...
- 洛谷 P2015 二叉苹果树 题解
题面 裸的树上背包: 设f[u][i]表示在以u为子树的树种选择i条边的最大值,则:f[u][i]=max(f[u][i],f[u][i-j-1]+f[v][k]+u到v的边权); #include ...
随机推荐
- 查看Linux系统版本的命令
1.lsb_release -a,即可列出所有版本信息: [root@S-CentOS ~]# lsb_release -a LSB Version: :base-4.0-amd64:base-4.0 ...
- 强化学习读书笔记 - 10 - on-policy控制的近似方法
强化学习读书笔记 - 10 - on-policy控制的近似方法 学习笔记: Reinforcement Learning: An Introduction, Richard S. Sutton an ...
- Scrapy爬去哪儿~上海一日游门票并存入MongoDB数据库
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZwAAAGGCAYAAABPDDfEAAAgAElEQVR4nOy9C3Rb1Z3/+z1Hkm35mT
- 高可用Kubernetes集群-3. etcd高可用集群
五.部署高可用etcd集群 etcd是key-value存储(同zookeeper),在整个kubernetes集群中处于中心数据库地位,以集群的方式部署,可有效避免单点故障. 这里采用静态配置的方式 ...
- 【ML系列】简单的二元分类——Logistic回归
对于了解机器学习中二元分类问题的来源与分析,我认为王树义老师这篇文章讲的非常好,通俗且易懂: http://blog.sciencenet.cn/blog-377709-1121098.html 但王 ...
- Python爬虫入门(5):URLError异常处理
大家好,本节在这里主要说的是URLError还有HTTPError,以及对它们的一些处理. 1.URLError 首先解释下URLError可能产生的原因: 网络无连接,即本机无法上网 连接不到特定的 ...
- hive 2以上版本启动异常 Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
hive2.0以上的版本启动时 抛出 “Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreCli ...
- VMware提示无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件解决方案
1.右键单击[我的电脑],选择[管理] 2.在[服务]中找到VMware Workstation Server服务右键启动
- MYSQL报警:Warning: Using a password on the command line interface can be insecure.
问题描述:执行下面的语句,sql是执行成功了,但是出现了一个报警,报警看上去始终不舒服 mysql -hip -Pport -uuser -ppassword -e "use db;dele ...
- 查看dll依赖项
win7 系统: 开始-->所有程序->vs2012文件夹->vs tools->对应的命令提示符 输入命令: dumpbin /dependents 你的文件(可以是exe, ...