P2014 [CTSC1997]选课

Miku

从叶子结点开始,自下而上得跑分组背包

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int s[301];
struct b{
	int to;
	int ne;
}e[301];
int son[301];
int p;
int dp[301][301];
int so[301][301];
int cnt[301];
int head[301];
void add(int f,int to){
	p++;
	e[p].ne=head[f];
	e[p].to=to;
	head[f]=p;
}
int x,y;
void dpp(int now){
	son[now]=1;
	for(int i=head[now];i;i=e[i].ne){
		cnt[now]++;
		so[now][cnt[now]]=e[i].to;
		dpp(e[i].to);
		son[now]+=son[e[i].to];
	}
		dp[now][1]=s[now];
	for(int i=1;i<=cnt[now];++i){
		for(int j=m+1;j;--j){//因为有0点并且必选		
			for(int k=0;k<j;++k){
					dp[now][j]=max(dp[now][j],dp[now][j-k]+dp[so[now][i]][k]);
			}
		}
	}

}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d%d",&x,&y);
		add(x,i);
		s[i]=y;
	}
	dpp(0);
	cout<<dp[0][m+1];//多出来的时不存在的0 
	return 0;
}
posted @ 2020-08-06 22:29  Simex  阅读(144)  评论(0编辑  收藏  举报