题目链接:
题解思路:
这道题要用到动态规划中的背包
可以把 涂漆节点的个数 理解为背包容量 ,则每个节点的重量为1
dp[a][b] 表示包含a(根节点)的共b个节点的最大权值
然后通过后序遍历从下往上先求得子节点的最大权值,依次向上背包
最后得到的dp[1][v]则为答案
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define MAXN 105
using namespace std;
vector<int>q[MAXN]; //
int dp[MAXN][MAXN];
int n,v;
int max(int a,int b)
{
return a>b?a:b;
}
void dfs_package(int loc)
{
for(int i=0;i<q[loc].size();i++)
dfs_package(q[loc][i]);
dp[loc][0]=0;
for(int i=0;i<q[loc].size();i++)
for(int j=v;j>=2;j--) //j只能到2 因为必须要保证dp[x][1]不被改变(包含根节点)
for(int k=1;k<j;k++) //取第i棵子书的k个节点
dp[loc][j]=max(dp[loc][j],dp[loc][j-k]+dp[q[loc][i]][k]);
}
int main()
{
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++)
scanf("%d",&dp[i][1]);
int a,b;
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
if(a<b)
q[a].push_back(b);
else
q[b].push_back(a);
}
dfs_package(1);
cout<<dp[1][v]<<endl;
return 0;
}