题目链接:https://www.luogu.org/problemnew/show/P2015

题意:给定一颗结点个数为n的树,有n-1条边,每条边有个权值,树根为1。现在给出q <=n,问剪枝后保留q条边后的边的权值最大是多少。

思路:首先要知道这道题有个隐含条件,如果某条边被保留,那么从根节点到这个点路径上的所有点都必须保留。

   我们用dp[i][j]表示顶点i的子树上保留j条边的最大权值和是多少。

   给出状态转移方程:dp[x][j]=max(dp[x][j] , dp[x][j-1-k]+dp[y][k]+edge[i].w)

   其中x是当前结点,y是x的一个子结点,k表示结点y上保留的边数,0<j<=min(siz[x],q),0=<k<=min(siz[y],j-1)。因为要把x和y之间的边算上,所以是j-1-k。

   其中j需要倒序枚举,类似01背包。

AC代码:

#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=; struct node{
int v,w,nex;
}edge[maxn<<]; int n,q,cnt,head[maxn],siz[maxn];
int dp[maxn][maxn]; void adde(int u,int v,int w){
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs(int x,int f){
for(int i=head[x];i;i=edge[i].nex){
int y=edge[i].v;
if(y==f) continue;
dfs(y,x);
siz[x]+=siz[y]+;
for(int j=min(siz[x],q);j;--j)
for(int k=;k<=min(siz[y],j-);++k)
dp[x][j]=max(dp[x][j],dp[x][j--k]+dp[y][k]+edge[i].w);
}
} int main(){
scanf("%d%d",&n,&q);
for(int i=;i<n;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
adde(v,u,w);
}
dfs(,-);
printf("%d\n",dp[][q]);
return ;
}

最新文章

  1. OpenCv全景图像拼接
  2. salesforce 零基础学习(二十六)自定义图表chart简单介绍(使用apex和VF实现)
  3. SharePoint Online 创建门户网站系列之创建栏目
  4. 【C++沉思录】句柄2
  5. 【crunch bang】tint2配置2
  6. Velocity原理
  7. android ProgressBar 样式讲解
  8. RubyWin32Api Win32OLE
  9. 奇异值分解(SVD) --- 几何意义
  10. NSDateFormatter 问题
  11. MVC引用CSS文件の正确姿势
  12. Express4+Mongodb极简入门实例
  13. C++类的常成员函数
  14. 笔记:I/O流-内存映射文件
  15. STM32L476应用开发之四:触摸屏驱动与数据交互
  16. 离线环境下安装ansible,借助有网环境下pip工具
  17. 【题解】ID分配
  18. [转载]drop、truncate和delete的区别
  19. C# 调用Sql server 执行存储过程总是返回-1
  20. golang web框架 beego 学习 (三) beego获取参数

热门文章

  1. Mysql存储时间字段
  2. luoguP1996 约瑟夫问题
  3. Java中indexOf的用法
  4. Android中的“再按一次返回键退出程序”代码实现
  5. 通过nginx转发,用外网连接阿里云的redis,报Unexpected end of stream的解决办法
  6. LightGBM GPU python版本安装
  7. Java多线程-线程中止
  8. Qt加载本地字体 .ttc或.ttf
  9. HearthBuddy的狂野和休闲模式来回切换
  10. [Java]一段尚未雕琢的分词代码