您的位置:首页 > 其它

hdu 1011(树形dp)

2013-09-08 00:13 274 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011


思路:dp[i][j]表示以i为根的子树派遣j个士兵占领的最大价值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 111

int dp[MAXN][MAXN];
int num[MAXN],val[MAXN];
int n,m;
bool mark[MAXN];
vector<vector<int> >G;

void dfs(int u)
{
mark[u]=true;
for(int i=num[u];i<=m;i++){
dp[u][i]=val[u];
}
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(mark[v])continue;
dfs(v);
for(int i=m;i>=num[u];i--){
for(int j=1;j+i<=m;j++){
if(dp[v][j]){
dp[u][i+j]=max(dp[u][i+j],dp[u][i]+dp[v][j]);
}
}
}
}
}

int main()
{
int u,v,ans;
while(~scanf("%d%d",&n,&m)){
if(n==-1&&m==-1)break;
G.clear();
G.resize(n+2);
for(int i=1;i<=n;i++){
scanf("%d%d",&num[i],&val[i]);
num[i]=(num[i]+19)/20;
}
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(dp,0,sizeof(dp));
memset(mark,false,sizeof(mark));
dfs(1);
ans=0;
for(int i=1;i<=m;i++){
ans=max(ans,dp[1][i]);
}
printf("%d\n",ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: