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 }
View Code

 

posted @ 2017-08-13 21:00  Blue233333  阅读(226)  评论(0编辑  收藏  举报