BZOJ1086 [SCOI2005]王室联邦(树分块)

把树的结点分块,块内结点连通且个数[b,3b]。

一遍DFS,维护一个栈,设置一个虚拟栈底以保证连通,递归返回时判断栈内元素个数是否大于等于b,是则划分为一个块,最后剩下的与最后一个块划分在一起。

http://blog.csdn.net/popoqqq/article/details/42772237

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 #define MAXN 1111
 5 struct Edge{
 6     int v,next;
 7 }edge[MAXN<<1];
 8 int NE,head[MAXN];
 9 void addEdge(int u,int v){
10     edge[NE].v=v; edge[NE].next=head[u];
11     head[u]=NE++;
12 }
13 int b;
14 int root[MAXN],belong[MAXN],bn;
15 int stack[MAXN],top;
16 void dfs(int u,int fa){
17     int buttom=top;
18     for(int i=head[u]; i!=-1; i=edge[i].next){
19         int v=edge[i].v;
20         if(v==fa) continue;
21         dfs(v,u);
22         if(top-buttom>=b){
23             root[++bn]=u;
24             while(top!=buttom){
25                 belong[stack[top--]]=bn;
26             }
27         }
28     }
29     stack[++top]=u;
30 }
31 int main(){
32     int n,u,v;
33     scanf("%d%d",&n,&b);
34     NE=0;
35     memset(head,-1,sizeof(head));
36     for(int i=1; i<n; ++i){
37         scanf("%d%d",&u,&v);
38         addEdge(u,v);
39         addEdge(v,u);
40     }
41     dfs(1,1);
42     if(top && bn==0){
43         putchar('0');
44         return 0;
45     }
46     while(top){
47         belong[stack[top--]]=bn;
48     }
49     printf("%d\n",bn);
50     for(int i=1; i<=n; ++i) printf("%d ",belong[i]);
51     putchar('\n');
52     for(int i=1; i<=bn; ++i) printf("%d ",root[i]);
53     return 0;
54 }

 

posted @ 2016-04-02 16:11  WABoss  阅读(156)  评论(0编辑  收藏  举报