#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define M 105
int n,m,k;
vector<int> G[M];
int value[M];
int xi[M][M];
int ma = 0;
int ar[M];
int arr[M];
int vis[M];
inline int maxx(int a,int b)
{
return a>b?a:b;
}
void reinit()
{
memset(vis,0,sizeof(vis));vis[1]=1;
memset(xi,0,sizeof(xi));
for(int i=1;i<=n;i++)
if(!G[i].empty()) G[i].clear();
}
void deals(int v,int num)
{
for(int i=0;i<(int)G[v].size();i++)
if(xi[G[v][i]][num]>ma) ma = xi[G[v][i]][num];
}
void deal(int v)
{
for(int i=0;i<(int)G[v].size();i++)
{
memset(ar,0,sizeof(ar));
if(i==0)
{
for(int j=0;j<m;j++)
xi[v][j+1] = xi[G[v][0]][j];
}
else
{
for(int j=0;j<=m;j++)
for(int k=1;k<=m-j;k++)
ar[j+k] = maxx(ar[j+k],xi[G[v][i]][j]+xi[v][k]);
}
for(int j=0;j<=m;j++)
{
xi[v][j] = maxx(xi[v][j],ar[j]);
}
}
for(int i=1;i<=m;i++)
{
ma = 0;
deals(v,i);
xi[v][i] = maxx(ma,xi[v][i]+value[v]);
}
}
void dfs(int v)
{
if((int)G[v].size()==0)
{
for(int i=1;i<=m;i++)
xi[v][i]=value[v];
return ;
}
for(int j=0;j<(int)G[v].size();j++)
{
if(!vis[G[v][j]])
{
vis[G[v][j]] = 1;
dfs(G[v][j]);
}
}
deal(v);
}
void init()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
reinit();
int sum = 0;
for(int i=1;i<=n;i++)
{
scanf("%d",&value[i]);
sum += value[i];
}
for(int i=0;i<n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);//为什么一定要这个,还要vis数组标记,不是树么!!求解释,花了两个小时找个这样的错误是无语的
}
if(m>=n) {printf("%d\n",sum);continue;}
if(m==0) {puts("0");continue;}
if(n==1) {printf("%d\n",value[1]);continue;}
dfs(1);
printf("%d\n",xi[1][m]);
}
return ;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
init();
return 0;
}
Sicily 1138. 寻宝之旅 树形DP
最新推荐文章于 2022-08-20 22:57:29 发布