说好的动态规划呢,明明是贪心题(摔)
拿到这题首先我们模拟一下。
哎?点分治?好像啊
过了样例?
交上去试试?
呵呵呵呵呵呵呵呵呵
不如来贪心一下,每次重心有多个可以取的时候,取度数最大的那个……好像有道理
我有点方了。
不过至少我们得到了一个上界,答案不会超过[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; }