CF533B Work Group

原题链接

妙妙树形dp
\(u\)不选时,\(u\)的子节点个数为奇数还是偶数都可以
\(u\)选时,\(u\)的子节点个数必须为偶数
这样可以搞一个状态总数为\(N*2*2\)或者\(N*2\)的dp(前者更好理解)

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

#define fr first
#define se second
#define et0 exit(0);
#define rep(i, a, b) for(int i = (int)(a); i <= (int)(b); i ++)
#define rrep(i, a, b) for(int i = (int)(a); i >= (int)(b); i --)
#define IO ios::sync_with_stdio(false),cin.tie(0);

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef unsigned long long ULL;

const int INF = 0X3f3f3f3f, N = 1e6 + 10, MOD = 1e9 + 7;
const double eps = 1e-7, pi = acos(-1);

int n;
LL a[N];
LL f[N][2];

vector<int> g[N];

void dfs(int u, int fa) {
	f[u][1] = -1e18;
	rep (i, 0, g[u].size() - 1) {
		int v = g[u][i];
		dfs(v, u);
		LL x = f[u][0], y = f[u][1];
		f[u][0] = max(f[v][1] + y, f[v][0] + x);
		f[u][1] = max(f[v][0] + y, f[v][1] + x);
	}
	f[u][1] = max(f[u][1], f[u][0] + a[u]);
}

void work() {
	cin >> n;
	rep (i, 1, n) {
		int p;
		cin >> p >> a[i];
		if (p != -1) g[p].push_back(i);
	}
	
	dfs(1, 0);
	cout << max(f[1][0], f[1][1]) << endl;
}

signed main() {
	IO

	int test = 1;

	while (test--) {
		work();
	}

	return 0;
}
posted @ 2022-09-26 22:20  xhy666  阅读(63)  评论(0)    收藏  举报