二叉苹果树
#include <bits/stdc++.h> using namespace std; //二叉苹果树 //j代表保留树枝的总数 //做法一:当j大于子树所能保存的最大的边的时候,值都是最大的边对应的值,导致肯定没有刚好分配边数的值大 int n,dp[110][110]={0},G[100+10][100+10],k,sons[100+10]={0}; void dfs(int rt,int f){ int lc=-1,rc=-1; for(int i=1;i<=n;i++){ if(G[rt][i]==-1||f==i) continue; if(lc==-1) lc=i; else rc=i; } if(lc==-1&&rc==-1) {sons[rt]=1;return;} dfs(lc,rt); dfs(rc,rt); sons[rt]=sons[lc]+sons[rc]+1; //做法2:如果超过最大边数那么设为0,这样以后即使超了,也不会max // for(int i=1;i<=sons[rt]-1;i++){ for(int i=1;i<=k;i++){ dp[rt][i]=max(dp[lc][i-1]+G[rt][lc],dp[rc][i-1]+G[rt][rc]); //左子树保留多少树枝,这是包括往左右走的花费 for(int j=1;j<i;j++){ // 做法三:子树保存的边太多就不要了 if(j>sons[lc]||i-j>sons[rc]) continue; dp[rt][i]=max(dp[rt][i],dp[lc][j-1]+dp[rc][i-j-1]+G[rt][rc]+G[rt][lc]); } } } int main() { cin>>n>>k; memset(G,255, sizeof(G)); for(int i=1;i<n;i++){ int x,y,z; cin>>x>>y>>z; G[x][y]=G[y][x]=z; } dfs(1,-1); cout<<dp[1][k]<<endl; return 0; }