Luogu-P2015 二叉苹果树
题面传送门: Luogu-P2015
题目描述
给定一棵 \(n\) 个节点的以 \(1\) 为根的二叉树(严格二叉), 树边有边权. 现在需要剪去一些树边(剪边定义为: 若剪去一条边 \((u,v)\), 在删除该边的同时也必须舍弃以 \(v\) 为根的整个子树), 问在留下 \(m\) 条边时边权之和的最大值.
\(n \le 100,m<n\).
题目分析
非常明显的树形DP.
设 \(F[u][j]\) 表示以 \(u\) 为根的子树中留下 \(j\) 条边的最大权值, 答案即为 \(F[1][m]\).
1.状态转移方程:
\[ F[u][j]=max\{F[u][j-k-1]+F[v][k]+w_{u,v}\}\\ 1 \le j \le min(m,size[u]),0 \le k \le min(j-1,size[v]) \]
其中 \(v\) 是 \(u\) 的一个子节点, \(w_{u,v}\) 表示边 \((u,v)\) 的权值, \(size[i]\) 表以 \(i\) 为根的子树中边的数量, \(k\) 是枚举出来的, 表示在以 \(v\) 为根的子树中选 \(k\) 条边.
2.解释:
- 若在子树 \(v\) 中选中了 \(k\) 条边, 那么在其他子树中只能选择 \(k-j-1\) 条边(因为当前这条边 \((u,v)\) 必须选择, 不然不合法)
- \(k\) 的范围必须小于等于 \(j-1\) , 因为当 \(k=j\) 时, \(j-k-1\) 的值为 \(-1\), 显然不合法.
3.复杂度:
因每个点只会访问一次, 每次访问枚举需要 \(n^2\) 的复杂度, 故总复杂度为 \(O(n^3)\), 并且常数极小.
实现细节
- 记忆化搜索.
- \(j,k\) 需要倒序枚举, 原因同 \(01\) 背包.
- 记忆化搜索的同时处理 \(size\) 数组.
代码
/*********************************************************** Author : EndSaH* Email : 2499808100@qq.com* Created Time : 2018-11-17 09:36* FileName : temp.cpp* *******************************************************/#include <cstdio>
#include <cctype>
#include <iostream>namespace Fast_IO
{/*{{{*/char ibuf[1 << 20], obuf[1 << 20], stk[20];char *ipos = ibuf, *iend = ibuf, *opos = obuf, *oend = obuf + (1 << 20), *stkpos = stk;inline char Getchar(){return ipos == iend and (iend = (ipos = ibuf) + fread(ibuf, 1, 1 << 20, stdin), ipos == iend) ? EOF : *ipos++;}inline void Putchar(char c){if(opos == oend){fwrite(obuf, 1, 1 << 20, stdout);opos = obuf;}*opos++ = c;}inline int read(){register int num = 0;register bool flag = false;register char c;while(!isdigit(c = Getchar()))flag |= c == '-';while(num = (num << 3) + (num << 1) + (c ^ 48), isdigit(c = Getchar()));return flag ? -num : num;}inline void write(int x){if(x < 0)Putchar('-'), x = -x;do{*stkpos++ = x % 10 ^ 48;x /= 10;} while(x);while(stkpos-- != stk)Putchar(*stkpos);++stkpos;}
}/*}}}*/
using namespace Fast_IO;const int maxN = 102;int n, q, x, y, z, cnt;
int head[maxN], F[maxN][maxN], size[maxN];
bool vis[maxN];struct Chain
{int v, w, next;
} chain[maxN << 1];template<typename _Tp>
inline bool chkmin(_Tp& x, const _Tp& y)
{/*{{{*/return x > y ? (x = y, true) : false;
}/*}}}*/template<typename _Tp>
inline bool chkmax(_Tp& x, const _Tp& y)
{/*{{{*/return x < y ? (x = y, true) : false;
}/*}}}*/inline void Link(int u, int v, int w)
{chain[++cnt] = (Chain){v, w, head[u]};head[u] = cnt;
}void DFS(int u)
{vis[u] = true;for(register int i = head[u]; i; i = chain[i].next){int v = chain[i].v;if(vis[v])continue;DFS(v);size[u] += size[v] + 1;for(register int j = std::min(q, size[u]); j; --j)for(register int k = std::min(j - 1, size[v]); ~k; --k)chkmax(F[u][j], F[u][j - k - 1] + F[v][k] + chain[i].w);}
}int main()
{
#ifndef ONLINE_JUDGEfreopen("temp.in", "r", stdin);freopen("temp.out", "w", stdout);
#endifn = read(), q = read();for(register int i = 1; i < n; ++i){x = read(), y = read(), z = read();Link(x, y, z);Link(y, x, z);}DFS(1);write(F[1][q]);fwrite(obuf, 1, opos - obuf, stdout);return 0;
}
转载于:https://www.cnblogs.com/EndSaH/p/9975180.html
Luogu-P2015 二叉苹果树相关推荐
- luogu P2015 二叉苹果树
一道qq姐和dtx很早就做了的题www 想学树形dp就是从这道题开始的 然后做了几道题 之后被难住了 于是回来做这道题 首先这道题保证了是一棵二叉树 emmmmm 然后一个dp数组 dp[u][j] ...
- 洛谷P2015 二叉苹果树【树形dp】
P2015 二叉苹果树 时间限制 1.00s 内存限制 125.00MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点 ...
- 洛谷 P2015 二叉苹果树 题解
洛谷 P2015 二叉苹果树 题解 洛谷 P2015 题目 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有NNN个结点(叶子点或者树枝分叉点),编号为1-NNN ...
- 洛谷P2015 二叉苹果树
题目描述 有一棵苹果树,如果树枝有分叉,一定是分二叉(就是说没有只有一个儿子的结点) 这棵树共有 NN 个结点(叶子点或者树枝分叉点),编号为 1 \sim N1∼N,树根编号一定是 11. 我们用一 ...
- P2015 二叉苹果树 树形DP
题目描述 有一棵苹果树,如果树枝有分叉,一定是分二叉(就是说没有只有一个儿子的结点) 这棵树共有 NN 个结点(叶子点或者树枝分叉点),编号为 1 \sim N1∼N,树根编号一定是 11. 我们用一 ...
- P2015 二叉苹果树
传送门 这道题要用到链式前向星... 非常标准的树形背包DP 只要理解了,题就不难 只要理解了...... 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树 ...
- 洛谷 P2015 二叉苹果树
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 洛谷2015 二叉苹果树 树形DP
https://www.luogu.org/problemnew/show/P2015 二叉苹果树 时间限制: 1 Sec 内存限制: 128 MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 ...
- 二叉苹果树(树型DP+背包)
二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号 ...
- AcWing1074. 二叉苹果树(树形DP)题解
题目传送门 题目描述 有一棵二叉苹果树,如果树枝有分叉,一定是分两叉,即没有只有一个儿子的节点. 这棵树共 N 个节点,编号为 1 至 N,树根编号一定为 1. 我们用一根树枝两端连接的节点编号描述一 ...
最新文章
- 主流微服务全链路监控系统之战
- 淮阴工学院计算机期末考选择题题库,淮阴工学院计算机导论题库.doc
- 带宽限制下的视觉实体属性传播
- 【MFC系列-第12天】Windows系统对话框
- 小白必看!JS中循环语句大集合
- js中自执行函数(function(){})()和(function(){}())区别
- 7月发布?华为李昌竹确认Mate 50系列:会来的但不是现在
- tf 矩阵行和列交换_tf.transpose函数的用法讲解
- 《R语言实战》读书笔记--学习张丹日志
- 记一次KAFKA TroubleShooting
- TBS X5内核SDK静态集成jar完美解决方案
- Kotlin知识积累——let,with,run,apply,alse的用法
- TPA6100A2DGKR立体声音频功率放大器
- pwnable.kr第二遍---mistake
- [Tableau] 销售团队绩效分析与相关策略指导
- MySQL数据库密码忘了,怎么修改密码,找回密码。
- 读懂千行百业,萤石物联云平台全新能力发布
- ubuntu与centos哪个更适合做服务器。
- bootstrap国内cdn库
- 【python】带你采集房源数据并作房价分析
热门文章
- 计算机中常用于比较的图表有,2013年职称计算机Excel考点:常用图表类型
- 分享Android资深架构师的成长之路,建议收藏
- 关注IT精英:微利时代如何赚大钱 (转载)
- python 图片文字识别orc
- 计算机桌面底下显示条,详细教您电脑屏幕出现条纹怎么办
- w10用计算机卸载,win10电脑怎么卸载软件
- vijos 清点人数
- 1577 例题3 数字转换(LOJ10155) 约数计算 树上最长链(两次找最大深度)
- 关于OSPF 5类LSA中Forwarding Address
- PMP 考点 第三章 项目经理的角色