二叉苹果树

#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;
}
原文地址:https://www.cnblogs.com/MorrowWind/p/13056454.html