Sicily 1138. 寻宝之旅 树形DP

OJ

#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)