首页 > 代码库 > Bzoj1086 [SCOI2005]王室联邦
Bzoj1086 [SCOI2005]王室联邦
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
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
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]王室联邦
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。