题解:AT_arc083_c [ARC083E] Bichrome Tree

posted on 2024-11-26 10:59:13 | under | source

小清新题。

一棵子树对外界的影响只关注其黑、白权值之和。考虑 \(u\) 子树,令 \(u\) 为黑色,那么黑点权值确定,不难发现白点权值应当尽量小,因为本题只需满足点权非负即可,所以白点权值较大的方案一定可以通过将权值移到 \(u\) 父亲的方式转化为权值和较小的方案。

那么进行树形 dp,目标是 \(u\) 子树黑点权值和为 \(X_u\) 且白点权值尽量小,\(u\) 权值随意所以令其它黑点权值和 \(\le X_u\) 即可。所以有状态 \(f_{u,i}\) 表示 \(u\) 子树黑点权值为 \(i\) 时白点权值和最小是多少。

考虑转移,记 \(g\)\(f_u\) 的滚动数组,新增 \(v\) 子树那么分类讨论 \(v\) 的颜色(是否和 \(u\) 一样即可):

  1. 均为黑色:\(f_{u,i+X_v}\gets g_i+f_{v,X_v}\)
  2. 为白色:\(f_{u,f_{v,X_v}}\gets g_i+X_v\)

读者可以结合贪心结论和 dp 转移来加深理解,其实本质是一样的:为了使第二种转移中尽量不越界,所以肯定要白点权值尽量小。

最后判断 \(f_{1,X_1}\) 是否有值,复杂度 \(O(nV)\)

代码

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define MIN(a, b) a = min(a, b)
const int N = 1e3 + 5, M = 5e3 + 5, inf = 1e7;
int n, pa, a[N], f[N][M], g[M];
vector<int> to[N];

inline void dfs(int u){
	for(int i = 0; i <= a[u]; ++i) f[u][i] = 0;
	for(auto v : to[u]){
		dfs(v);
		for(int i = 0; i <= a[u]; ++i) g[i] = f[u][i], f[u][i] = inf;
 		for(int i = 0; i <= a[u]; ++i){
			if(i + a[v] <= a[u]) MIN(f[u][i + a[v]], g[i] + f[v][a[v]]);
			if(i + f[v][a[v]] <= a[u]) MIN(f[u][i + f[v][a[v]]], g[i] + a[v]);
		}
	}
}
signed main(){
	cin >> n;
	for(int i = 2; i <= n; ++i) scanf("%lld", &pa), to[pa].push_back(i);
	for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
	dfs(1);
	if(f[1][a[1]] < inf) puts("POSSIBLE");
	else puts("IMPOSSIBLE");
	return 0;
}
posted @ 2026-01-15 08:14  Zwi  阅读(1)  评论(0)    收藏  举报