BZOJ1086 SCOI2005王室联邦
想学树上莫队结果做了个树分块。
看完题后想到了菊花图的形状认为无解,结果仔细一瞧省会可以在外省尴尬
对于每一颗子树进行深搜,一旦遇到加在一起大小达到B则将它们并为一省,因为他子树搜完以后没有分出块的大小是小于B的,而且他自己当前剩下的也是小于B的,所以可以放心和。
最后剩下的点肯定也小于B所以与最后一个省一合即可。当前子树根节点留给上面也是因为这个。
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1005; 4 int bel[N],size[N],cap[N],head[N],num,cnt,top,s[N],n,b; 5 struct node{ 6 int to,nex; 7 }e[N<<1]; 8 void add(int x,int y) 9 { 10 e[++cnt].nex=head[x];e[cnt].to=y;head[x]=cnt; 11 } 12 void dfs(int x,int fa) 13 { 14 s[++top]=x; 15 for(int i=head[x];i;i=e[i].nex) 16 { 17 int y=e[i].to; 18 if(y==fa)continue; 19 dfs(y,x); 20 if(size[x]+size[y]>=b){ 21 size[x]=0; 22 cap[++num]=x; 23 while(s[top]!=x)bel[s[top--]]=num; 24 } 25 else size[x]+=size[y]; 26 } 27 size[x]++; 28 } 29 int main() 30 { 31 scanf("%d%d",&n,&b); 32 if(n<b){ 33 puts("0");return 0; 34 } 35 int x,y,w; 36 for(int i=1;i<n;++i) 37 { 38 scanf("%d%d",&x,&y); 39 add(x,y);add(y,x); 40 } 41 dfs(1,0); 42 while(top)bel[s[top--]]=num; 43 printf("%d\n",num); 44 for(int i=1;i<=n;++i)printf("%d ",bel[i]); 45 printf("\n"); 46 for(int i=1;i<=num;++i)printf("%d ",cap[i]); 47 return 0; 48 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。