原题链接:https://ac.nowcoder.com/acm/problem/50505

题目大意:

有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点。这棵树共N个节点,标号1至N,树根编号一定为1。
我们用一根树枝两端连接的节点编号描述一根树枝的位置。一棵有四根树枝的苹果树,因为树枝太多了,需要剪枝。但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果。

解题思路:

一个二维数组的dp,记录第i个节点往下包括j个节点的最大值,递推公式:遍历的时候i要从大往小。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
typedef complex <double> cp;
#define debug(a) cout<<#a<<":"<<a<<endl;
#define fr freopen("in.txt","r",stdin);
#define Fill(x,a) memset(x,a,sizeof(x))
#define cpy(a,b) memcpy(a,b,sizeof(a))
const double PI = acos(-1);
const int INF=0x3f3f3f3f;
const int N=1e6+7;
const int mod=1e9+7;
int maxn,minn;
int T,n,m,q;
struct aa{
    int u,w,next;
}edge[N];
int head[N];
int cnt;
int dp[500][500];

void init(){
    cnt=1;
    Fill(head,0);
    return ;
}

void add(int u,int v,int w){
    edge[cnt].next=head[u];
    edge[cnt].u=v;
    edge[cnt].w=w;
    head[u]=cnt++;
    return ;
}


void dfs(int u,int p){
    int v,w;
    for(int i=head[u];i!=0;i=edge[i].next){
        v=edge[i].u;
        w=edge[i].w;
        if(v==p)    continue;
        dfs(v,u);
        for(int i=m;i>=1;i--){
            for(int j=1;j<=i;j++){
                dp[u][i]=max(dp[u][i],dp[v][j-1]+dp[u][i-j]+w);    
            }
        }
    }

}

int main(){
    int u,v,w;
    cin>>n>>m;
    init();
    for(int i=1;i<n;i++){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }
    dfs(1,0);
//    for(int i=1;i<=n;i++){
//        for(int j=0;j<=m;j++){
//            cout<<dp[i][j]<<" ";
//        }
//        cout<<endl;
//    }
    for(int i=1;i<=m;i++){
        maxn=max(dp[1][i],maxn);
    }
    cout<<maxn<<endl;



    return 0;
}