[二分答案] [树形dp] ABC246G Game on Tree 3

posted on 2024-04-20 13:52:23 | under | source

考虑二分答案。从 \(A\) 的角度出发,判定能否使答案 \(\le mid\)

\(a_i> mid\) 视为非法点;反之是合法点。

然后定义 \(f_u\) 表示从 \(u\) 开始至少还需多少次操作才能使得无法到达非法点。

转移是容易的。最后 \(f_1=0\)\(mid\) 不合法,反之合法。

代码

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

const int N = 2e5 + 5;
int n, a[N], u, v, f[N], L, R;
vector<int> to[N];
pair<int, int> q[N];

inline void dfs(int u, int fa, int p){
	f[u] = 0;
	for(auto v : to[u]) if(v ^ fa) dfs(v, u, p), f[u] += f[v];
	f[u] = max(0, f[u] - 1) + (a[u] > p);
}
inline bool check(int p) {dfs(1, 0, p); return f[1] == 0;}
int main(){
	cin >> n;
	for(int i = 2; i <= n; ++i) scanf("%d", &a[i]);
	for(int i = 1; i < n; ++i) scanf("%d%d", &u, &v), to[u].push_back(v), to[v].push_back(u);
	int L = -1, R = 1e9 + 5, mid;
	while(L + 1 < R){
		mid = L + R >> 1;
		if(check(mid)) R = mid;
		else L = mid;
	}
	cout << R;
	return 0;
}
posted @ 2026-01-12 20:13  Zwi  阅读(2)  评论(0)    收藏  举报