BZOJ 1086 王室联邦

http://www.lydsy.com/JudgeOnline/problem.php?id=1086

思路:贪心,每次当储存的儿子大于等于B时,分出一个块,这样每次每个块至多为2B,这样剩下的没有被分的块小于B,可以加入任意一个块,都是合法的。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 int tot,go[200005],first[200005],next[200005],n,m;
 7 int top,c[200005],pd,size[200005],cap[200005],belong[200005],sz;
 8 int read(){
 9     char ch=getchar();int t=0,f=1;
10     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
11     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
12     return t*f;
13 }
14 void insert(int x,int y){
15     tot++;
16     go[tot]=y;
17     next[tot]=first[x];
18     first[x]=tot;
19 }
20 void add(int x,int y){
21     insert(x,y);insert(y,x);
22 }
23 void dfs(int x,int fa){
24     c[++top]=x;
25     for (int i=first[x];i;i=next[i]){
26         int pur=go[i];
27         if (pur==fa) continue;
28         dfs(pur,x);
29         if (size[x]+size[pur]>=m){
30             cap[++sz]=x;size[x]=0;
31             while (c[top]!=x) belong[c[top--]]=sz;
32         }else size[x]+=size[pur];
33     }
34     size[x]++;
35 }
36 void find(int x,int fa){
37     if (belong[x]) {
38         pd=belong[x];
39         return;
40     }
41     for (int i=first[x];i;i=next[i]){
42         int pur=go[i];
43         if (pur==fa) continue;
44         if (!pd) find(pur,x);
45     }
46 }
47 int main(){
48     n=read();m=read();
49     if (n<m){
50         printf("0\n");
51         return 0;
52     }
53     if (m==1){
54         printf("%d\n",n);
55         for (int i=1;i<=n;i++)
56          printf("%d ",i);
57         printf("\n");
58         for (int i=1;i<=n;i++)
59          printf("%d ",i);
60         printf("\n");
61         return 0;
62     }
63     for (int i=1;i<n;i++){
64         int x=read(),y=read();
65         add(x,y);
66     }
67     dfs(1,0);
68     pd=0;
69     int cnt=0,th;
70     for (int i=1;i<=n;i++)
71      if (!belong[i]) cnt++,th=1;
72     if (cnt>=m){
73         sz++;
74         cap[sz]=th;
75         for (int i=1;i<=n;i++)
76          if (!belong[i]) belong[i]=sz;
77     } 
78     for (int i=1;i<=n;i++)
79       if (!belong[i]){
80          if (!pd) find(i,0);
81          if (pd) belong[i]=pd;
82     }
83     printf("%d\n",sz);
84     for (int i=1;i<=n;i++)
85      printf("%d ",belong[i]);
86     printf("\n"); 
87     for (int i=1;i<=sz;i++) 
88      printf("%d ",cap[i]);
89     printf("\n"); 
90 }

 

posted @ 2016-06-14 09:06  GFY  阅读(188)  评论(0编辑  收藏  举报