#P2871. USACO(126)动态规划(树形DP)4:产奶比赛P6079 [USACO06MAR] Milk Team Select G

USACO(126)动态规划(树形DP)4:产奶比赛P6079 [USACO06MAR] Milk Team Select G

Description

[USACO06MAR] Milk Team Select G


【题目描述】

Farmer John 的 $N(1 \le N \le 500)$ 头奶牛打算参加一场世界级的产奶比赛 (Multistate Milking Match-up,MMM),他们已经摸清了其他队的实力。他们的总产奶量只要大于等于 $X$ 加仑($1 \leq X \leq 10^6$),就能赢得胜利。

每头奶牛都能为全队贡献一定量的牛奶,数值在 $-10^4$ 到 $10^4$ 加仑之间(为啥有负数?因为有些奶牛会打翻其他奶牛产的牛奶)。

MMM 的目标是通过合作,增进家庭成员间的默契。为了支持比赛精神,奶牛们希望在赢得比赛的前提下,有尽可能多对奶牛间存在直系血缘关系。当然,所有奶牛都是女性,因此这里的直系血缘关系就是母女关系。

现在 FJ 摸清了所有奶牛间的血缘关系,希望算出一个团队在赢得胜利的前提下,最多有多少对奶牛存在血缘关系。注意:如果一个团队由某头奶牛和她的母亲和外祖母组成的话,这个团队只有两对血缘关系(她和她的母亲,她的母亲和外祖母)。

【输入格式】

第一行两个整数 $N,X$。

接下来 $N$ 行,每行两个整数,第一个整数是它能为团队贡献的产奶量,第二个整数为它的母亲的编号,如果她的母亲不在牛群里,这个数字为 $0$。

保证血缘关系不会出现环。

【输出格式】

输出在获胜的前提下,一个团队中最多存在多少血缘关系。

特别地,如果不存在一个团队能获胜,输出 $-1$。


【样例输入】

5 8
-1 0
3 1
5 1
-3 3
2 0

【样例输出】

2

【提示】

最优的队伍包含 $1,2,3,5$ 这四头奶牛,总产奶量为 $9$ 加仑,共有两对血缘关系($1,2$ 和 $1,3$)。

虽然 $2,3,5$ 这个组合产奶量更大,但是这个组合里没有血缘关系。

Hint

by hansang:
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int f[N][N][2], n, a[N];
vector<int> G[N]; 
void dfs(int x){
	f[x][0][0]=0;
	f[x][0][1]=a[x];
	for(int y: G[x]){
		dfs(y);
		for(int i=n; i>=0; i--){
			for(int j=i; j>=0; j--){
				f[x][i][0]=max(f[x][i][0], f[x][j][0]+max(f[y][i-j][1], f[y][i-j][0]));
				if(i-j>=1) f[x][i][1]=max(f[x][i][1], f[x][j][1]+f[y][i-j-1][1]);
				f[x][i][1]=max(f[x][i][1], f[x][j][1]+f[y][i-j][0]);
			}
		}
	}
}
void work(){
	int m; scanf("%d%d", &n, &m);
	for(int i=1; i<=n; i++){
		int x=i, y; scanf("%d%d", &a[i], &y);
		G[y].push_back(x);
	} 
	memset(f, -0x3f, sizeof(f));
	a[0]=0; dfs(0);
	for(int i=n; i>=0; i--){ 
		if(f[0][i][0]<m) continue;
		printf("%d\n", i);
		return ;
	}
	printf("-1\n");
}
int main(){
	work();
	return 0;
}