CODEVS5565 二叉苹果树

n<=100个点的根为1的二叉树,树边上有苹果,求保留Q<=n条边的最多苹果数。

树形DP,f[i][j]--节点i为根的子树保留j条边最优方案,f[i][0]=0,f[i][j]=max(f[lc[i]][k-1]+f[rc[i]][j-k-1]+v[lc[i]]+v[rc[i]]),这是左右都选的情况,再加只选左只选右方案即可。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 //#include<iostream>
 6 using namespace std;
 7
 8 int n,Q;
 9 #define maxn 111
10 int f[maxn][maxn];
11 struct Edge{int to,next,v;};
12 struct Tree
13 {
14     Edge edge[maxn<<1];
15     int lc[maxn],rc[maxn],v[maxn];
16     int first[maxn],le;
17     Tree() {memset(first,0,sizeof(first));le=2;}
18     void in(int x,int y,int v)
19     {
20         edge[le].to=y;
21         edge[le].v=v;
22         edge[le].next=first[x];
23         first[x]=le++;
24     }
25     void insert(int x,int y,int v)
26     {
27         in(x,y,v);
28         in(y,x,v);
29     }
30     void dfs(int x,int fa)
31     {
32         lc[x]=rc[x]=0;
33         for (int i=first[x];i;i=edge[i].next)
34             if (edge[i].to!=fa)
35             {
36                 if (!lc[x]) lc[x]=edge[i].to;
37                 else rc[x]=edge[i].to;
38                 v[edge[i].to]=edge[i].v;
39                 dfs(edge[i].to,x);
40             }
41     }
42     void dp(int x)
43     {
44         if (lc[x]) dp(lc[x]);
45         if (rc[x]) dp(rc[x]);
46         f[x][0]=0;
47         for (int i=1;i<=Q;i++)
48         {
49             f[x][i]=max(f[lc[x]][0]+f[rc[x]][i-1]+v[rc[x]],f[lc[x]][i-1]+f[rc[x]][0]+v[lc[x]]);
50             for (int j=1;j<=i-1;j++)
51                 f[x][i]=max(f[x][i],f[lc[x]][j-1]+f[rc[x]][i-j-1]+v[lc[x]]+v[rc[x]]);
52         }
53     }
54 }t;
55 int x,y,v;
56 int main()
57 {
58     scanf("%d%d",&n,&Q);
59     for (int i=1;i<n;i++)
60     {
61         scanf("%d%d%d",&x,&y,&v);
62         t.insert(x,y,v);
63     }
64     t.dfs(1,0);
65     t.dp(1);
66     printf("%d\n",f[1][Q]);
67     return 0;
68 }

时间: 2024-12-29 11:57:58

CODEVS5565 二叉苹果树的相关文章

二叉苹果树|codevs5565|luoguP2015|树形DP|Elena

二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=100)

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

二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树: 2   5 \  / 3  4 \  / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 程序名:apple 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=

luogu P2015 二叉苹果树

P2015 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2        5 \     / 3   4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<

[Luogu2015]二叉苹果树(树形dp)

[Luogu2015] 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1&l

luoguP2015 二叉苹果树

luoguP2015 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<

MZOJ 1134 &amp;&amp; LuoGu P2015 二叉苹果树

MZOJ 1134 && LuoGu P2015 二叉苹果树     [传送门] #include<bits/stdc++.h> using namespace std; const int maxn=500; int N,Q; int head[maxn],k=0; int w[maxn][maxn],f[maxn][maxn]; struct edge{ int v,w,nxt; }e[maxn<<1]; void init(){ freopen("i

二叉苹果树(由根分为左子树和右子树两部分情况)

有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点.这棵树共  个节点,标号  至 ,树根编号一定为 . 我们用一根树枝两端连接的节点编号描述一根树枝的位置.一棵有四根树枝的苹果树,因为树枝太多了,需要剪枝.但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果. 输入格式 第一行两个数 N和 Q,N 表示树的节点数, Q表示要保留的树枝数量. 接下来 N-1行描述树枝信息,每行三个整数,前两个是它连接的节点的编号,第三个数是这根树枝上苹果数量. 输出格式 输

二叉苹果树

题意/Description:     有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果.给定需要保留的树枝数量,求出最多能留住多少苹果. 读入/Input:     第1行2个数,N和Q. N表示在树枚举的点数.Q表示应

洛谷—— P2015 二叉苹果树

https://www.luogu.org/problem/show?pid=2015 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式