传送门
就是给树分块。
对于一个节点。
如果它的几棵子树加起来超过了下限,就把它们分成一块。
这样每次可能会剩下几个节点。
把它们都加入栈中最顶上那一块就行了。
代码:
#include<bits/stdc++.h>
#define N 1005
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int first[N],cnt=0,n,b,tot=0,stk[N],top=0,ans[N],belong[N];
struct edge{int v,next;}e[N<<1];
inline void add(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;}
inline void dfs(int p,int fa){
int tmp=top;
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
dfs(v,p);
if(top-tmp>=b){
ans[++tot]=p;
while(top!=tmp)belong[stk[top--]]=tot;
}
}
stk[++top]=p;
}
int main(){
n=read(),b=read();
for(int i=1;i<n;++i){
int u=read(),v=read();
add(u,v),add(v,u);
}
dfs(1,1);
while(top)belong[stk[top--]]=tot;
printf("%d\n",tot);
for(int i=1;i<=n;++i)printf("%d%c",belong[i],i==n?'\n':' ');
for(int i=1;i<=tot;++i)printf("%d ",ans[i]);
return 0;
}