和
n
o
i
p
2018
noip2018
noip2018的那道有点像
先二分答案
反正是要最大化向上传的链
从最小的开始枚举找第一个加起来
≥
k
\geq k
≥k的匹配
还要考虑把不合法的往上传
用
s
e
t
set
set做
复杂度
O
(
n
l
o
g
2
n
)
O(nlog^2n)
O(nlog2n)
本人的分类讨论稍微有些复杂
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int N=100005;
vector<int> e[N];
multiset<int> st[N];
int n,k,fg;
int dfs(int u,int fa){
st[u].clear();
if(!fg)return 0;
for(int &v:e[u])if(v!=fa){
st[u].insert(dfs(v,u)+1);
}
int up=0;
while(st[u].size()>2&&fg){
int now=*st[u].bg();
st[u].erase(st[u].bg());
if(now>=k){continue;}
multiset<int>::iterator it=st[u].lower_bound(k-now);
if(it==st[u].end()){
if(up){fg=0;break;}
up=now;
}
else{
st[u].erase(it);
}
}if(!fg)return 0;
if(u!=1){
if(st[u].size()==2){
int v1=*st[u].bg(),v2=*st[u].rbegin();
if(up){
if(v1+v2<k){fg=0;return 0;}
}
else{
if(v1>=k||v2>=k){
up=min(v1,v2);
}
else {
if(v1+v2<k){fg=0;return 0;}
}
}
}
if(st[u].size()==1){
int v1=*st[u].bg();
if(up){
if(v1<k){fg=0;return 0;}
}
else{
up=v1;
}
}}
if(u==1){
if(up)fg=0;
if(st[u].size()==2){
int v1=*st[u].bg(),v2=*st[u].rbegin();
if(v1+v2<k)fg=0;
}
if(st[u].size()==1){
int v1=*st[u].bg();
if(v1<k)fg=0;
}
}
return up;
}
inline bool check(int _k){
k=_k,fg=1;
dfs(1,0);
return fg;
}
int main(){
n=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
e[u].pb(v),e[v].pb(u);
}
int l=1,r=n,res=1;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))l=mid+1,res=mid;
else r=mid-1;
}
cout<<res<<'\n';
return 0;
}