题面传送门: 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 二叉苹果树相关推荐

  1. luogu P2015 二叉苹果树

    一道qq姐和dtx很早就做了的题www 想学树形dp就是从这道题开始的 然后做了几道题 之后被难住了 于是回来做这道题 首先这道题保证了是一棵二叉树 emmmmm 然后一个dp数组 dp[u][j] ...

  2. 洛谷P2015 二叉苹果树【树形dp】

    P2015 二叉苹果树 时间限制 1.00s 内存限制 125.00MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点 ...

  3. 洛谷 P2015 二叉苹果树 题解

    洛谷 P2015 二叉苹果树 题解 洛谷 P2015 题目 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有NNN个结点(叶子点或者树枝分叉点),编号为1-NNN ...

  4. 洛谷P2015 二叉苹果树

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分二叉(就是说没有只有一个儿子的结点) 这棵树共有 NN 个结点(叶子点或者树枝分叉点),编号为 1 \sim N1∼N,树根编号一定是 11. 我们用一 ...

  5. P2015 二叉苹果树 树形DP

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分二叉(就是说没有只有一个儿子的结点) 这棵树共有 NN 个结点(叶子点或者树枝分叉点),编号为 1 \sim N1∼N,树根编号一定是 11. 我们用一 ...

  6. P2015 二叉苹果树

    传送门 这道题要用到链式前向星... 非常标准的树形背包DP 只要理解了,题就不难 只要理解了...... 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树 ...

  7. 洛谷 P2015 二叉苹果树

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

  8. 洛谷2015 二叉苹果树 树形DP

    https://www.luogu.org/problemnew/show/P2015 二叉苹果树 时间限制: 1 Sec  内存限制: 128 MB 题目描述 有一棵苹果树,如果树枝有分叉,一定是分 ...

  9. 二叉苹果树(树型DP+背包)

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

  10. AcWing1074. 二叉苹果树(树形DP)题解

    题目传送门 题目描述 有一棵二叉苹果树,如果树枝有分叉,一定是分两叉,即没有只有一个儿子的节点. 这棵树共 N 个节点,编号为 1 至 N,树根编号一定为 1. 我们用一根树枝两端连接的节点编号描述一 ...

最新文章

  1. 主流微服务全链路监控系统之战
  2. 淮阴工学院计算机期末考选择题题库,淮阴工学院计算机导论题库.doc
  3. 带宽限制下的视觉实体属性传播
  4. 【MFC系列-第12天】Windows系统对话框
  5. 小白必看!JS中循环语句大集合
  6. js中自执行函数(function(){})()和(function(){}())区别
  7. 7月发布?华为李昌竹确认Mate 50系列:会来的但不是现在
  8. tf 矩阵行和列交换_tf.transpose函数的用法讲解
  9. 《R语言实战》读书笔记--学习张丹日志
  10. 记一次KAFKA TroubleShooting
  11. TBS X5内核SDK静态集成jar完美解决方案
  12. Kotlin知识积累——let,with,run,apply,alse的用法
  13. TPA6100A2DGKR立体声音频功率放大器
  14. pwnable.kr第二遍---mistake
  15. [Tableau] 销售团队绩效分析与相关策略指导
  16. MySQL数据库密码忘了,怎么修改密码,找回密码。
  17. 读懂千行百业,萤石物联云平台全新能力发布
  18. ubuntu与centos哪个更适合做服务器。
  19. bootstrap国内cdn库
  20. 【python】带你采集房源数据并作房价分析

热门文章

  1. 计算机中常用于比较的图表有,2013年职称计算机Excel考点:常用图表类型
  2. 分享Android资深架构师的成长之路,建议收藏
  3. 关注IT精英:微利时代如何赚大钱 (转载)
  4. python 图片文字识别orc
  5. 计算机桌面底下显示条,详细教您电脑屏幕出现条纹怎么办
  6. w10用计算机卸载,win10电脑怎么卸载软件
  7. vijos 清点人数
  8. 1577 例题3 数字转换(LOJ10155) 约数计算 树上最长链(两次找最大深度)
  9. 关于OSPF 5类LSA中Forwarding Address
  10. PMP 考点 第三章 项目经理的角色