首页 > 代码库 > Bzoj1086 [SCOI2005]王室联邦

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 }

 

Bzoj1086 [SCOI2005]王室联邦