题解 CF627D 【Preorder Test】
题解地址:
[CF627D]Preorder Test - skylee's Blog
题目大意:
一个
思路:
二分答案
对于以结点
若
若
时间复杂度
源代码:
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<forward_list>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=2e5+1;
int w[N],f[N],k,size[N],ans,root;
std::forward_list<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_front(v);
e[v].push_front(u);
}
void dfs(const int &x,const int &par) {
f[x]=size[x]=1;
int max1=0,max2=0;
for(register auto &y:e[x]) {
if(y==par) continue;
dfs(y,x);
size[x]+=size[y];
if(f[y]==size[y]) {
f[x]+=f[y];
} else {
if(f[y]>max1) std::swap(f[y],max1);
if(f[y]>max2) std::swap(f[y],max2);
}
}
f[x]=w[x]<k?0:f[x]+max1;
ans=std::max(ans,f[x]+max2);
}
inline int calc() {
dfs(root,ans=0);
return ans;
}
int main() {
const int n=getint(),m=getint();
for(register int i=1;i<=n;i++) w[i]=getint();
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
root=std::min_element(&w[1],&w[n]+1)-w;
int l=*std::min_element(&w[1],&w[n]+1);
int r=*std::max_element(&w[1],&w[n]+1);
while(l<=r) {
k=(l+r)>>1;
if(calc()>=m) {
l=k+1;
} else {
r=k-1;
}
}
printf("%d\n",l-1);
return 0;
}