没有完全理解这题,
m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点
dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解
状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>
#define N 105
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
#define P system("pause")
using namespace std;
int dp[N][N],vis[N];
vector<int> mp[N];
int n,m;
struct node
{
int x,y;
}s[N];
void dfs(int p)
{
int i,j,k;
int temp=ceil(s[p].x/20.0);
for(i=temp;i<=m;i++) dp[p][i]=s[p].y;
vis[p]=1;
for(i = 0; i < mp[p].size();i++)
{
int t = mp[p][i];
if(vis[t]) continue;
dfs(t);
for(j=m;j>=temp;j--)
{
for(k=1; k<=j-temp; k++)//留下temp攻打p
dp[p][j]=max(dp[p][j],dp[p][j-k]+dp[t][k]);
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
while(cin>>n>>m)
{
if(n == -1 && m == -1) break;
int ans = 0;
int i;
for(i = 0; i <= n; i++)
mp[i].clear();
memset(dp,0,sizeof(dp));//不一定要恰好装满,所以 初始化为0
memset(vis,0,sizeof(vis));
for(i = 1; i <= n; i++)
cin>>s[i].x>>s[i].y;
for(i = 0; i < n-1; i++){
int a,b;
cin>>a>>b;
mp[a].push_back(b);
mp[b].push_back(a);
}
if(m == 0)
{
cout<<0<<endl;
continue;
}
dfs(1);
int j;
// for(i = 1 ; i <= n; i++){
// for(j = 0; j <= m; j++)
// cout<<dp[i][j]<<" ";
// cout<<endl;
//}
cout<<dp[1][m]<<endl;
}
return 0;
}