二分+判断:
#include<bits/stdc++.h>
using namespace std;
vector<int> t[250000];
int val[250000];
int dp[250000];
void dfs(int v,int pa,int x){//
int tmp=0;
for(auto u:t[v]){
if(u!=pa){
dfs(u,v,x);
tmp+=dp[u];
}
}
dp[v]=max(tmp-1,0)+(int)(val[v]>=x);//以v为游戏起点,保证Aoki赢,在高桥走第一步之前,所需要消去的
} //价值>=val[v]的数量,减去一个是由于Aoki先走
bool check(int x){//判断Aoki一定能赢,即判断dp[0]==0
dfs(1,0,x); //即高桥从vertex1出发后,Aoki需要消去0个即可保证高桥走不到val>=x的树结点
return dp[1]==0;
}
int main(){
int n;cin>>n;
int maxx=0;
for(int i=2;i<=n;i++){
cin>>val[i];
maxx=max(maxx,val[i]);
}
for(int i=1;i<n;i++){//存图
int u,v;cin>>u>>v;
t[u].push_back(v);
t[v].push_back(u);
}
int i=1,j=maxx;
while(i<=j){//二分
int mid = (i+j)>>1;
if(!check(mid)){
i=mid+1;
}else{
j=mid-1;
}
}
cout<<j;
return 0;
}