Bzoj1086 [SCOI2005]王室联邦

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
Submit: 1749  Solved: 1056

Description

  “余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成
员来管理。他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个不同的城市之间有且仅有一条
直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个
城市。每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经
过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。一个城市可以作为多个省的省会。聪明的
你快帮帮这个国王吧!

Input

  第一行包含两个数N,B(1<=N<=1000, 1 <= B <= N)。接下来N-1行,每行描述一条边,包含两个数,即这
条边连接的两个城市的编号。

Output

  如果无法满足国王的要求,输出0。否则输出数K,表示你给出的划分方案中省的个数,编号为1..K。第二行输
出N个数,第I个数表示编号为I的城市属于的省的编号,第三行输出K个数,表示这K个省的省会的城市编号,如果
有多种方案,你可以输出任意一种。

Sample Input

8 2
1 2
2 3
1 8
8 7
8 6
4 6
6 5

Sample Output

3
2 1 1 3 3 3 3 2
2 1 8

HINT

 

Source

 

树 贪心 (伪)树分块

听说是树分块裸题……喜+1系列

按DFS序遍历整棵树,发现子树大小大于B,就把它们划成一块

这样分出来,每棵子树的大小都在B~2B之间。

最后还会剩下一些零碎的结点,它们的总数小于B(不然就被划分了),把它们拼到最近的块里,该块尺寸不会超过3B,满足要求。

n<B时无解

 

写啥WA啥系列,34行把cnt写成u挂了一次

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<queue>
 6 using namespace std;
 7 const int mxn=2010;
 8 int read(){
 9     int x=0,f=1;char ch=getchar();
10     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
12     return x*f;
13 }
14 struct edge{
15     int v,nxt;
16 }e[mxn<<1];
17 int hd[mxn],mct=0;
18 void add_edge(int u,int v){
19     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
20 }
21 //
22 int n,B;
23 int t[mxn],C[mxn],sz[mxn];
24 int st[mxn],top=0,cnt=0;
25 void DFS(int u,int fa){
26     st[++top]=u;
27     for(int i=hd[u],v;i;i=e[i].nxt){
28         v=e[i].v;
29         if(v==fa)continue;
30         DFS(v,u);
31         if(sz[u]+sz[v]>=B){
32             C[++cnt]=u;
33             while(st[top]!=u){
34                 t[st[top--]]=cnt;
35             }
36             sz[u]=0;
37         }
38         else sz[u]+=sz[v];
39     }
40     ++sz[u];
41     return;
42 }
43 void DFS2(int u,int fa,int c){
44     if(!t[u])t[u]=c;
45     else c=t[u];
46     for(int i=hd[u];i;i=e[i].nxt){
47         if(e[i].v==fa)continue;
48         DFS2(e[i].v,u,c);
49     }
50     return;
51 }
52 int main(){
53     int i,j,u,v;
54     n=read();B=read();
55     if(n<B){printf("0\n");return 0;}
56     for(i=1;i<n;i++){
57         u=read();v=read();
58         add_edge(u,v);add_edge(v,u);
59     }
60     DFS(1,0);
61     //
62     if(!cnt){C[cnt=1]=1;}
63     DFS2(1,0,cnt);
64     printf("%d\n",cnt);
65     for(i=1;i<=n;i++){printf("%d ",t[i]);}printf("\n");
66     for(i=1;i<=cnt;i++){printf("%d ",C[i]);}printf("\n");
67     return 0;
68 }

 

posted @ 2017-03-25 22:11  SilverNebula  阅读(226)  评论(0编辑  收藏  举报
AmazingCounters.com