题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17662

题意:给一棵边有权值的二叉树,节点编号为1~n,1是根节点。求砍掉一些边,只保留q条边,这q条边构成的子树的根节点要求是1,求这颗子树的最大权值。

分析:1.dp[u][i]表示已以u为根节点的子树,保留了i个节点的最大权值。每条边的权值,把它看作是连接的两个节点中的儿子节点的权值。那么总共要保留m+1个节点。

所以有:dp[u][i]=max(dp[u][i],dp[v][k]+dp[u][i-k]+w).ans=dp[1][m+1].

2.dp[u][i]表示u为根节点的子树,保留了i个条边的最大权值。在以u点为根节点的子树中选择了k条边,那么u的儿子节点v代表的子树中至多选k-1条边,因为如果在v子树中选边,那么u到v的边必选。

所以有:dp[u][i]=max(dp[u][i],dp[u][i-k]+dp[v][k-1]+w).ans=dp[1][m].

方法1的代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 110
#define clr(a) (memset(a,0,sizeof(a)))
using namespace std;
struct edge
{
int v,w,next;
edge(){}
edge(int v,int w,int next):v(v),w(w),next(next){}
}e[*N];
int head[N],dp[N][N],num[N],tot,n,m;
void addedge(int u,int v,int w)
{
e[tot]=edge(v,w,head[u]);
head[u]=tot++;
}
void dfs(int u,int fa)
{
num[u]=;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v,w=e[i].w;
if(v==fa)continue;
dfs(v,u);
num[u]+=num[v];
for(int j=num[u];j>=;j--)
for(int k=;k<j&&k<=num[v];k++)//注意这里k<j.因为子树根节点u点必选,在子树节点中至多选j-1个
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]+w);
}
}
int main()
{
int u,v,w;
while(scanf("%d%d",&n,&m)>)
{
memset(head,-,sizeof(head));
clr(dp);tot=;
for(int i=;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
dfs(,-);
printf("%d\n",dp[][m+]);
}
}

方法2的代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 110
#define clr(a) (memset(a,0,sizeof(a)))
using namespace std;
struct edge
{
int v,w,next;
edge(){}
edge(int v,int w,int next):v(v),w(w),next(next){}
}e[*N];
int head[N],dp[N][N],tot,n,m;
void addedge(int u,int v,int w)
{
e[tot]=edge(v,w,head[u]);
head[u]=tot++;
}
void dfs(int u,int fa)
{
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v,w=e[i].w;
if(v==fa)continue;
dfs(v,u);
for(int j=m;j>=;j--)
for(int k=;k<=j;k++)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k-]+w);
}
}
int main()
{
int u,v,w;
while(scanf("%d%d",&n,&m)>)
{
memset(head,-,sizeof(head));
clr(dp);tot=;
for(int i=;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
dfs(,-);
printf("%d\n",dp[][m]);
}
}

ural1018(树形dp)的更多相关文章

  1. URAL1018 Binary Apple Tree(树形DP)

    题目大概说一棵n结点二叉苹果树,n-1个分支,每个分支各有苹果,1是根,要删掉若干个分支,保留q个分支,问最多能保留几个苹果. 挺简单的树形DP,因为是二叉树,都不需要树上背包什么的. dp[u][k ...

  2. 树形DP小结

    树形DP1.简介:树是一种数据结构,因为树具有良好的子结构,而恰好DP是从最优子问题更新而来,那么在树上做DP操作就是从树的根节点开始深搜(也就是记忆化搜索),保存每一步的最优结果.tips:树的遍历 ...

  3. 树形 DP 总结

    树形 DP 总结 本文转自:http://blog.csdn.net/angon823/article/details/52334548 介绍 1.什么是树型动态规划 顾名思义,树型动态规划就是在“树 ...

  4. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  5. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  6. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  7. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  8. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  9. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  10. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

随机推荐

  1. 基于visual Studio2013解决面试题之0708字符串全排列

     题目

  2. hdu 4687 Boke and Tsukkomi

    Dancing link twice. Find the maximum combination numbers in the first time. Enumerate each node, dan ...

  3. .Net 配置文件——继承ConfigurationSection实现自己定义处理类处理自己定义配置节点

    除了使用继承IConfigurationSectionHandler的方法定义处理自己定义节点的类.还能够通过继承ConfigurationSection类实现相同效果. 首先说下.Net配置文件里一 ...

  4. javascript学习笔记--迭代函数

    概要 这里的迭代函数指的是对数组对象的操作方法,js数组共有五个迭代函数:every.fifter.forEach.map.some. 1.every every方法,返回值为Boolean类型,tr ...

  5. uploadify,实际开发案例【选择完文件点击上传才上传】

    <script type="text/javascript"> )+Math.floor(Math.random()*)+']-'; //设置随机文件前缀. $k(fu ...

  6. Mina2 研究总结

    一.Mina框架. Mina的框架大概是这么个样子: 底层由Java 的NIO 1.0实现 核心架构应该是这样: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZX ...

  7. 怎样从ext3升级到ext4?

    Ext4 文件系统提供了更佳的性能和可靠性,具有了更为丰富的功能,那么,怎样从ext3升级到ext4呢? 首先,我们须要保证系统支持ext4,一般来说,内核版本号在2.6.28及以上的版本号才支持ex ...

  8. CorePlot学习

    阅读这篇文章,指出它在国外    原文地址:https://github.com/core-plot/core-plot/wiki/High-Level-Design-Overview 强烈推荐阅读该 ...

  9. Linux 多线程串口通信

    大概流程就是打开一个串口.然后进行串口设置.开启二个线程,一个线程写数据,另一个线程读数据. 代码如下: #include <stdio.h> #include <stdlib.h& ...

  10. java学习笔记13--比较器(Comparable、Comparator)

    java学习笔记13--比较器(Comparable.Comparator) 分类: JAVA 2013-05-20 23:20 3296人阅读 评论(0) 收藏 举报 Comparable接口的作用 ...