洛谷 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 }