题目描述

有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)

这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。

现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。

给定需要保留的树枝数量,求出最多能留住多少苹果。

输入输出格式

输入格式:

第1行2个数,N和Q(1<=Q<= N,1<N<=100)。

N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。

每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。

每根树枝上的苹果不超过30000个。

输出格式:

一个数,最多能留住的苹果的数量。

Solution

树形DP一道模板题,考虑DP

DP[ i ][ j ]表示在以i为结点的子树中保留j个边能得到的最大苹果数量

状态转移方程如下

         for(int j=min(num[cur],m);j;--j)
for(int k=min(num[ev],j-);k>=;--k)
DP[cur][j]=max(DP[cur][j],DP[cur][j-k-]+DP[ev][k]+e[i].w);

cur表示当前遍历到的节点,num[cur]表示以cur为节点的子树的边数(可以通过DFS预处理)

j枚举当前节点子树的保留边的个数,k表示当前边的v节点的子树的保留的边的个数,DP[cur][j]可以由保留j-k-1条边的前提下保留一个子树的k个节点转移过来。

那么问题来了,如果要正确转移我们需要在处理num数组的前提下从叶节点转移,并且枚举到每条边,如何做到呢

考虑DFS的遍历顺序和树的结构是一样的,我们可以在回溯的过程中DP,这样就完美了

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define maxn 1505
#define re register
using namespace std;
int DP[maxn][maxn<<];
int cnt,ans,n,x,num[maxn],y,z,head[maxn],m;
bool vis[maxn];
struct Edge{
int v,w,nxt;
}e[maxn<<];
void add(int u,int v,int w)
{
e[++cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
int dfs(int cur)
{
for(int i=head[cur];i;i=e[i].nxt)
{
int ev=e[i].v;
if(!vis[ev])
{
vis[ev]=;
num[cur]++;
num[cur]+=dfs(ev); for(int j=min(num[cur],m);j;--j)
for(int k=min(num[ev],j-);k>=;--k)
DP[cur][j]=max(DP[cur][j],DP[cur][j-k-]+DP[ev][k]+e[i].w);
}
}
return num[cur];
}
int main()
{
scanf("%d%d",&n,&m);
for(re int i=;i<=n-;++i)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
vis[]=;
dfs();
printf("%d\n",DP[][m]);
return ;
}

【P2015】二叉苹果树 (树形DP分组背包)的更多相关文章

  1. P2015 二叉苹果树[树形dp+背包]

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  2. P2015 二叉苹果树 (树形动规)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  3. 二叉苹果树——树形Dp(由根到左右子树的转移)

    题意:给出一个二叉树,每条边上有一定的边权,并且剪掉一些树枝,求留下 Q 条树枝的最大边权和. ( 节点数 n ≤100,留下的枝条树 Q ≤ n ,所有边权和 ∑w[i] ≤30000 ) 细节:对 ...

  4. 【Luogu】P2015二叉苹果树(DP,DFS)

    题目链接 设f[i][j][k]表示给以i为根节点的子树分配j条可保留的树枝名额的时候,状态为k时能保留的最多苹果. k有三种情况. k=1:我只考虑子树的左叉,不考虑子树的右叉,此时子树能保留的最多 ...

  5. P2015 二叉苹果树,树形dp

    P2015 二叉苹果树 题目大意:有一棵二叉树性质的苹果树,每一根树枝上都有着一些苹果,现在要去掉一些树枝,只留下q根树枝,要求保留最多的苹果数(去掉树枝后不一定是二叉树) 思路:一开始就很直接的想到 ...

  6. 洛谷 P2015 二叉苹果树 (树上背包)

    洛谷 P2015 二叉苹果树 (树上背包) 一道树形DP,本来因为是二叉,其实不需要用树上背包来干(其实即使是多叉也可以多叉转二叉),但是最近都刷树上背包的题,所以用了树上背包. 首先,定义状态\(d ...

  7. P2015 二叉苹果树

    P2015 二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接 ...

  8. 洛谷p2015二叉苹果树&yzoj1856多叉苹果树题解

    二叉 多叉 有一棵苹果树,如果树枝有分叉,可以是分多叉,分叉数k>=0(就是说儿子的结点数大于等于0)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1~N,树根编号一定是1.我们用一根树枝两 ...

  9. Codevs1378选课[树形DP|两种做法(多叉转二叉|树形DP+分组背包)---(▼皿▼#)----^___^]

    题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...

随机推荐

  1. 【Java基础】【16List集合】

    16.01_集合框架(去除ArrayList中重复字符串元素方式)(掌握) A:案例演示 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同) 思路:创建新集合方式 /** * A:案 ...

  2. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->用户管理模块新增“重置用户密码”功能

    不管是什么系统登录用户都有忘记密码的时候,忘记密码就进入不了系统.系统应该可以提供重置用户密码的功能.在我们框架中重置用户密码功能一般用用户管理员来完成.当然如果做得复杂点还可以由用户自己来重置(如: ...

  3. Docker最全教程——从理论到实战(二)

    上篇内容链接: https://www.cnblogs.com/codelove/p/10030439.html Docker和ASP.NET Core Docker 正在逐渐成为容器行业的事实标准, ...

  4. 2.计算机组成-数字逻辑电路 门电路与半加器 异或运算半加器 全加器组成 全加器结构 反馈电路 振荡器 存储 D T 触发器 循环移位 计数器 寄存器 传输门电路 译码器 晶体管 sram rom 微处理 计算机

    现代计算机的各个部件到底是如何通过逻辑电路构成的呢   半加器 我们说过了门电路 看似简单的三种门电路却是组成了整个逻辑电路的根基 真值表--其实就是根据输入输出状态枚举罗列出来的所有可能 比如有一台 ...

  5. 深度学习(Deep Learning)资料大全(不断更新)

    Deep Learning(深度学习)学习笔记(不断更新): Deep Learning(深度学习)学习笔记之系列(一) 深度学习(Deep Learning)资料(不断更新):新增数据集,微信公众号 ...

  6. xshell连接虚拟机详解--技术流ken

    xshell连接虚拟机 第一步:网络模式更改为桥接模式 第二步:重启网络 [root@ken1 ~]# systemctl restart network 第三步:获取IP地址 输入命令ip a 第四 ...

  7. 使用顶级 VSCode 扩展来加快开发 JavaScript

    使用顶级 VSCode 扩展来加快开发 JavaScript 发表于 2018年08月24日 by 愚人码头 被浏览 3,942 次 分享到:   小编推荐:掘金是一个面向程序员的高质量技术社区,从 ...

  8. 在ASP.NET MVC 项目中 使用 echarts 画统计图

    echarts 官方地址:http://echarts.baidu.com/ 一.根据图中的数据怎么从数据库中获取并组装成对应格式: 从数据库中获取对应数据,然后在项目中引用Newtonsoft.Js ...

  9. [日常] nginx记录post数据

    1.使用log_format指令来更改日志格式,该指令只能放在http{}段 log_format  日志名  '日志内容'; server { access_log /var/log/nginx/d ...

  10. java Calendar的学习分享

    前言: 在我们的日常生活中,常常能看见时间.如:在我们的手机里,在一些网站上也能随处看到时间.那我们在项目的开发中,也常常涉及到时间的处理,对于我们经常会遇到和处理的问题.Java中专门为我们处理时间 ...