POI 2004 Cave

说好的动态规划呢,明明是贪心题(摔)

拿到这题首先我们模拟一下。

哎?点分治?好像啊

过了样例?

交上去试试?


呵呵呵呵呵呵呵呵呵

不如来贪心一下,每次重心有多个可以取的时候,取度数最大的那个……好像有道理


我有点方了。

不过至少我们得到了一个上界,答案不会超过[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;
}


你可能感兴趣的:(POI 2004 Cave)