POI 2004 Cave

来源:互联网 发布:linux 知乎 编辑:程序博客网 时间:2024/05/23 11:55

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

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

哎?点分治?好像啊

过了样例?

交上去试试?


呵呵呵呵呵呵呵呵呵

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


我有点方了。

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


0 0
原创粉丝点击