[二分答案] [树形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;
}

浙公网安备 33010602011771号