洛谷 P2015 二叉苹果树

P2015 二叉苹果树

和选课差不多

但是并不是每条边的两边 谁是谁的父亲。。

根据边权确立点权

然后转二叉树

树形dp

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 1999
 4 int n,m,tot,head[maxn],fa[maxn],ls[maxn],rs[maxn],w[maxn],dp[maxn][maxn];
 5 struct Edge{
 6     int to,dis,next;
 7 }edge[maxn]; 
 8 
 9 void add(int u,int v,int d)
10 {
11     edge[++tot].to=v; edge[tot].dis=d; edge[tot].next=head[u]; head[u]=tot;
12     edge[++tot].to=u; edge[tot].dis=d; edge[tot].next=head[v]; head[v]=tot;
13 }
14 
15 void get(int now)
16 {
17     for(int i=head[now];i;i=edge[i].next)
18     {
19         if(fa[now]!=edge[i].to)
20         {
21             fa[edge[i].to]=now;
22             w[edge[i].to]+=edge[i].dis;
23             get(edge[i].to);
24         }
25     }
26 }
27 
28 int dfs(int i,int j)
29 {
30     if(i>n||j>m+1||i<1||j<1) return 0;
31     if(dp[i][j]) return dp[i][j];
32     for(int k=0;k<j;k++)
33         dp[i][j]=max(dp[i][j],dfs(ls[i],k)+dfs(rs[i],j-k-1)+w[i]);
34     dp[i][j]=max(dp[i][j],dfs(rs[i],j));
35     return dp[i][j];
36 }
37 
38 int main()
39 {
40     scanf("%d%d",&n,&m);
41     for(int i=1;i<n;i++)
42     {
43         int x,y,z;
44         scanf("%d%d%d",&x,&y,&z);
45         add(x,y,z);
46     }
47     add(1,0,0);
48     get(0);
49     for(int i=1;i<=n;i++)
50     {
51         if(!ls[fa[i]]) ls[fa[i]]=i;
52         else{
53             int dad=ls[fa[i]];
54             while(rs[dad]) dad=rs[dad];
55             rs[dad]=i;
56         }
57     }
58     printf("%d\n",dfs(ls[0],m+1));
59     return 0;
60 }
View Code

 

posted @ 2017-09-12 20:53  Alex丶Baker  阅读(92)  评论(0编辑  收藏  举报