“余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成
员来管理。他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个不同的城市之间有且仅有一条
直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个
城市。每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经
过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。一个城市可以作为多个省的省会。聪明的
你快帮帮这个国王吧!
第一行包含两个数N,B(1<=N<=1000, 1 <= B <= N)。接下来N-1行,每行描述一条边,包含两个数,即这
条边连接的两个城市的编号。
如果无法满足国王的要求,输出0。否则输出数K,表示你给出的划分方案中省的个数,编号为1..K。第二行输
出N个数,第I个数表示编号为I的城市属于的省的编号,第三行输出K个数,表示这K个省的省会的城市编号,如果
有多种方案,你可以输出任意一种。
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 }