有这样一个贪心的思路:当某一个点搜完某个儿子后,发现当前子树中没有被选入其他省的点数超过了B,就将其当做一个省,并把这个点作为省会(注意:这个点并没有进入这个省),显然可以发现此时每一个省的点数都小于2B。另外,当搜完后发现还有小于B的点,那么就将这些点都归入最后一个省,省的点数仍然小于3B。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1005 4 struct ji{ 5 int nex,to; 6 }edge[N<<1]; 7 int E,n,m,x,y,head[N],st[N],vis[N],s[N]; 8 void add(int x,int y){ 9 edge[E].nex=head[x]; 10 edge[E].to=y; 11 head[x]=E++; 12 } 13 void dfs(int k,int fa){ 14 int p=st[0]; 15 for(int i=head[k];i!=-1;i=edge[i].nex) 16 if (edge[i].to!=fa){ 17 dfs(edge[i].to,k); 18 if (st[0]-p>=m){ 19 s[++s[0]]=k; 20 while (p!=st[0])vis[st[st[0]--]]=s[0]; 21 } 22 } 23 st[++st[0]]=k; 24 } 25 int main(){ 26 scanf("%d%d",&n,&m); 27 memset(head,-1,sizeof(head)); 28 for(int i=1;i<n;i++){ 29 scanf("%d%d",&x,&y); 30 add(x,y); 31 add(y,x); 32 } 33 dfs(1,0); 34 while (st[0])vis[st[st[0]--]]=s[0]; 35 printf("%d\n",s[0]); 36 for(int i=1;i<=n;i++)printf("%d ",vis[i]); 37 printf("\n"); 38 for(int i=1;i<=s[0];i++)printf("%d ",s[i]); 39 }