【树形dp】二叉苹果树
2017-11-04 11:40
176 查看
题目描述
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树
2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
输入输出格式
输入格式:
第1行2个数,N和Q(1<=Q<= N,1< N<=100)。
N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。
输出格式:
一个数,最多能留住的苹果的数量。
输入输出样例
输入样例#1:
5 2
1 3 1
1 4 10
2 3 20
3 5 20
输出样例#1:
21
又是一道树形dp,代码几乎和有线电视网一样,有些细节需要注意:
dfs有点不同的是,加了一个fa标记不会回到父亲,还有是在回溯的时候sum加了1;
这里实际上是把边的权值下移到了点上,所以方程中:
f[x][j]=max(f[x][j],f[x][j-k]+f[edge[i].to][k-1]+edge[i].dis);
要从孩子节点中选k-1条,加上根节点本身(edge[i].dis),就恰好是j个点。
树形dp做的还是少,不同的问题dfs和f的涵义是不同的,要具体问题具体分析。
要沉的下心来,独立的做一道题。“给水泵大一点的压力”“不让他有出口”
难得一天的周末,noip 6天,赶紧练。
ps:下午有loli的考试
code:
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树
2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
输入输出格式
输入格式:
第1行2个数,N和Q(1<=Q<= N,1< N<=100)。
N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。
输出格式:
一个数,最多能留住的苹果的数量。
输入输出样例
输入样例#1:
5 2
1 3 1
1 4 10
2 3 20
3 5 20
输出样例#1:
21
又是一道树形dp,代码几乎和有线电视网一样,有些细节需要注意:
dfs有点不同的是,加了一个fa标记不会回到父亲,还有是在回溯的时候sum加了1;
这里实际上是把边的权值下移到了点上,所以方程中:
f[x][j]=max(f[x][j],f[x][j-k]+f[edge[i].to][k-1]+edge[i].dis);
要从孩子节点中选k-1条,加上根节点本身(edge[i].dis),就恰好是j个点。
树形dp做的还是少,不同的问题dfs和f的涵义是不同的,要具体问题具体分析。
要沉的下心来,独立的做一道题。“给水泵大一点的压力”“不让他有出口”
难得一天的周末,noip 6天,赶紧练。
ps:下午有loli的考试
code:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,x,y,z; struct Edge{ int next,to,dis; }edge[1001]; int f[1001][1001];//f[i][j]在以i为根的子树中选出j个节点(不包括自身)时的最大价值 int head[101],num_edge; void add_edge(int from,int to,int dis) { edge[++num_edge].next=head[from]; edge[num_edge].to=to; edge[num_edge].dis=dis; head[from]=num_edge; } int dfs(int x,int fa)//返回这个点为根的子树中节点的个数(不包括本身) { int sum=0; for (int i=head[x]; i!=0; i=edge[i].next) { if (edge[i].to==fa) continue;//防止走到父亲节点 (相当于做了标记) sum+=dfs(edge[i].to,x)+1; for (int j=sum; j>=1; j--) for (int k=1; k<=j; k++) f[x][j]=max(f[x][j],f[x][j-k]+f[edge[i].to][k-1]+edge[i].dis); } return sum; } int main() { scanf("%d%d",&n,&m); for (int i=1; i<=n-1; i++) { scanf("%d%d%d",&x,&y,&z); add_edge(x,y,z); add_edge(y,x,z); } dfs(1,0); printf("%d",f[1][m]); return 0; } /* 5 2 1 3 1 1 4 10 2 3 20 3 5 20 21 */
相关文章推荐
- URAL 1018 二叉苹果树(简单树形dp)
- 洛谷P2015 二叉苹果树(树形dp)
- [题解] P2015 二叉苹果树(树形DP)
- BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP
- 1380 没有上司的舞会 树形dp
- uva 11307 - Alternative Arborescence (树形dp)
- (树形DP) 最优连通子集(POJ1192)
- hdu1520 Anniversary party(树形dp)
- hdu1561-The more, The Better(树形dp)
- bzoj 2427: [HAOI2010]软件安装(Trajan+树形DP)
- MUTC 1 B - Hourai Jeweled 树形dp?
- HDU 3586 Information Disturbing (树形DP,二分)
- POJ 2486 Apple Tree 树形DP
- 树形DP求树的最小支配集,最小点覆盖,最大独立集
- Uva 10859 - Placing Lampposts 树形dp
- POJ2342:Anniversary party(树形dp)
- [HDU 2196] Computer 树形dp
- 【BZOJ 3090】 树形DP
- poj 1935(树形dp)
- BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP