说好的动态规划呢,明明是贪心题(摔)
拿到这题首先我们模拟一下。
哎?点分治?好像啊
过了样例?
交上去试试?
呵呵呵呵呵呵呵呵呵
不如来贪心一下,每次重心有多个可以取的时候,取度数最大的那个……好像有道理
我有点方了。
不过至少我们得到了一个上界,答案不会超过[log(n)]+1。
然后呢……
然后就不会做了QAQ
只好去Orz神犇的题解->OrzOrzOrz
扑通扑通跪下来。
啥也不说了让我静一静(抄题解的时候还抄错了一遍QAQ)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=50000+5;
struct Edge{int to,next;}e[N<<1];
int head[N],cnt;
void ins(int u,int v){
e[++cnt]=(Edge){v,head[u]};head[u]=cnt;
}
int f[N],bin[30],s[N],m,c[30];
void dp(int u,int fa){
int sv=0,cu=0,son=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;if(v==fa)continue;
dp(v,u);
sv|=s[v];
son++;
}
if(!son){
f[u]=0;
s[u]=1;
return;
}
memset(c,0,sizeof(c));
for(int i=head[u];i;i=e[i].next)
if(e[i].to!=fa)
for(int j=0;j<m;j++)
if(s[e[i].to]&(1<<j))c[j]++;
if(son>1)
for(int i=m-1;i>=0;i--)
if(c[i]>=2){
cu=i+1;
break;
}
for(int i=cu;i<m;i++)
if(!(sv&(1<<i))){
cu=i;
break;
}
s[u]=((sv>>cu)|1)<<cu;
f[u]=cu;
for(int i=head[u];i;i=e[i].next)
if(e[i].to!=fa)
f[u]=max(f[u],f[e[i].to]);
}
int main(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int n;scanf("%d",&n);m=log2(n)+1;
for(int i=1;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
ins(u,v);ins(v,u);
}
dp(1,0);
printf("%d\n",f[1]);
return 0;
}