类似于 LG-P3554 [POI2013]LUK-Triumphal arch,给定一棵树,有点权,B 初始在
与 LG-P3554 [POI2013]LUK-Triumphal arch 基本相同,对于本题依然考虑二分答案,对于当前的答案
对于二分的当然可以直接二分值域,不过这里可以考虑一个小剪枝,上界显然为点权的最小值,若根节点有多个子树,那么下界显然为根节点连接的节点的点权的最小值。
88123
45678910
11using namespace std;12using namespace __gnu_pbds;13
14mt19937 rnd(random_device{}());15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}16bool rnddd(int x){return rndd(1, 100) <= x;}17
18typedef unsigned int uint;19typedef unsigned long long unll;20typedef long long ll;21typedef long double ld;22
23template<typename T = int>24inline T read(void);25
26int N;27struct Edge{28 Edge* nxt;29 int to;30 OPNEW;31}ed[410000];32ROPNEW(ed);33Edge* head[210000];34
35int val[210000];36int mnval(INT_MAX), mxval(-1);37int f[210000];38
39void dfs(int k, int p = 1, int fa = 0){40 for(auto i = head[p]; i; i = i->nxt){41 if(SON == fa)continue;42 dfs(k, SON, p);43 f[p] += f[SON];44 }45 f[p] -= 1;46 f[p] = max(0, f[p]);47 f[p] += val[p] > k ? 1 : 0;48}49bool Check(int K){50 memset(f, 0, sizeof(f));51 dfs(K);52 return f[1] == 0;53}54int main(){55 N = read();56 for(int i = 2; i <= N; ++i)val[i] = read(), mxval = max(mxval, val[i]);57 for(int i = 1; i <= N - 1; ++i){58 int s = read(), t = read();59 head[s] = new Edge{head[s], t};60 head[t] = new Edge{head[t], s};61 if(s == 1)mnval = min(mnval, val[t]);62 if(t == 1)mnval = min(mnval, val[s]);63 }if(!head[1]->nxt)mnval = 0;64 int l = mnval, r = mxval;65 int ans(-1);66 while(l <= r){67 int mid = (l + r) >> 1;68 Check(mid) ? ans = mid, r = mid - 1 : l = mid + 1;69 }printf("%d\n", ans);70 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);71 return 0;72}73
74template<typename T>75inline T read(void){76 T ret(0);77 short flag(1);78 char c = getchar();79 while(c != '-' && !isdigit(c))c = getchar();80 if(c == '-')flag = -1, c = getchar();81 while(isdigit(c)){82 ret *= 10;83 ret += int(c - '0');84 c = getchar();85 }86 ret *= flag;87 return ret;88}update-2022_10_21 初稿