URAL1018 Binary Apple Tree(树形DP)

题目大概说一棵n结点二叉苹果树,n-1个分支,每个分支各有苹果,1是根,要删掉若干个分支,保留q个分支,问最多能保留几个苹果。

挺简单的树形DP,因为是二叉树,都不需要树上背包什么的。

  • dp[u][k]表示以u结点为根的子树保留k个分支最多能有的苹果数
  • 转移就是左子树若干个,右子树若干个转移。。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define MAXN 111
 6 struct Edge{
 7     int v,w,next;
 8 }edge[MAXN<<1];
 9 int NE,head[MAXN];
10 void addEdge(int u,int v,int w){
11     edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u];
12     head[u]=NE++;
13 }
14 int n,q,d[MAXN][MAXN];
15 void dp(int u,int fa){
16     d[u][0]=0;
17     int lson=-1,rson=-1,w1,w2;
18     for(int i=head[u]; i!=-1; i=edge[i].next){
19         int v=edge[i].v;
20         if(v==fa) continue;
21         if(lson==-1) lson=v,w1=edge[i].w;
22         else rson=v,w2=edge[i].w;
23         dp(v,u);
24     }
25     if(lson==-1) return;
26     if(rson==-1){
27         for(int i=0; i<q; ++i){
28             if(d[lson][i]==-1) continue;
29             d[u][i+1]=max(d[u][i+1],d[lson][i]+w1);
30         }
31         return;
32     }
33     for(int i=0; i<=q; ++i){
34         if(d[lson][i]==-1) continue;
35         for(int j=0; j<=q-i; ++j){
36             if(d[rson][j]==-1) continue;
37             if(i+j+2<=q) d[u][i+j+2]=max(d[u][i+j+2],d[lson][i]+d[rson][j]+w1+w2);
38             if(i==0 && j+1<=q) d[u][j+1]=max(d[u][j+1],d[rson][j]+w2);
39             if(j==0 && i+1<=q) d[u][i+1]=max(d[u][i+1],d[lson][i]+w1);
40         }
41     }
42 }
43 int main(){
44     int a,b,c;
45     while(~scanf("%d%d",&n,&q)){
46         NE=0;
47         memset(head,-1,sizeof(head));
48         for(int i=1; i<n; ++i){
49             scanf("%d%d%d",&a,&b,&c);
50             addEdge(a,b,c);
51             addEdge(b,a,c);
52         }
53         memset(d,-1,sizeof(d));
54         dp(1,1);
55         printf("%d\n",d[1][q]);
56     }
57     return 0;
58 }

 

posted @ 2016-05-06 17:24  WABoss  阅读(262)  评论(0编辑  收藏  举报