#include <iostream>
#include <vector>
using namespace std ;
const int maxn = 200+10 ;
const int root = 0; //所有森林的根,用于统一模板,本题可以不加
struct node
{
int father ;
vector<int> son ;
int bag[maxn];
int num ;
}dp[maxn];
int max(int a ,int b)
{
return a>b?a:b;
}
void push(int *bag,int cost,int weight) //强制添加物品
{
int i ;
for(i=maxn-1;i>=cost;i--) //maxn-1可改为v
{
bag[i] = bag[i-cost] + weight ;
}
for(;i>=0;i--)
{
bag[i] = 0 ;
}
}
void Union(int *a,int *b) //泛化物品的和,结果放在a里
{
for(int i=maxn-1;i>=0;i--) //maxn-1可改为v
{
for(int k=0;k<=i;k++)
{
a[i] = max( a[i] , a[i-k]+b[k] );
}
}
}
void init()
{
for(int i=0;i<maxn;i++)
{
dp[i].father = root ;
memset(dp[i].bag,0,sizeof(dp[i].bag));
dp[i].num = 0;
dp[i].son.clear();
}
}
void addEdge(int a ,int b)
{
dp[a].father = b;
dp[b].son.push_back(a);
}
void dfs(int ind)
{
int size = dp[ind].son.size();
//遍历所有儿子节点
for(int i=0;i<size;i++)
{
int son = dp[ind].son[i];
dfs(son);
//由儿子节点得出当前节点的值
Union(dp[ind].bag , dp[son].bag);
}
//所有非根节点强制添加当前物品、、、根节点是虚拟节点
if(ind != root)
push(dp[ind].bag , 1 , dp[ind].num);
}
int main()
{
int n,m;
while(cin>>n>>m,m&&n)
{
init();
int i;
for(i=1;i<=n;i++)
{
int a ,b ;
cin>>a>>b ;
addEdge(i,a);
dp[i].num = b ;
}
dfs(root);
cout<<dp[root].bag[m] <<endl;
}
return 0;
}
(树形dp 依赖背包)hdu1561
最新推荐文章于 2019-10-04 17:40:14 发布