这个贪心好妙啊。。。
蒟蒻的我看到1000就想了半天的n^2树形dp。
然后觉得这不可做啊??怎么记录方案啊??balabala...
然后就开始贪心。搞啊搞啊搞啊。。。。然后怒写很不简洁的代码各种分类讨论写到最后自己都不知道写了些啥。
网上一搜好妙啊。。。其实就是超过了B就开个块扔进去了。为啥这样是对的呢。。。这样肯定不超过2B(......==)啊摔!想题时的我为什么这么傻啊这么傻啊这么傻啊这么傻啊。。。。然后最后如果还有剩下的,合并到最后一个块里就可以了。不超过3B就是这么来的orz。。如果题意要求不超过2B那事情就麻烦了。。。
用栈暴力一搞就可以了。感觉是O(n)的???n<=1000误我啊。(感觉今天的吐槽格外的多啊。。暴躁是不对的QAQ)(要养生)
#include<bits/stdc++.h>
using namespace std;
#define rep(x,y,z) for (int x=y; x<=z; x++)
#define downrep(x,y,z) for (int x=y; x>=z; x--)
#define ms(x,y,z) memset(x,y,sizeof(z))
#define LL long long
#define repedge(x,y) for (int x=hed[y]; ~x; x=edge[x].nex)
inline int read(){
int x=0; int w=0; char ch=0;
while (ch<'0' || ch>'9') w|=ch=='-',ch=getchar();
while (ch>='0' && ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return w? -x:x;
}
const int N=1005;
int n,B,nedge,hed[N],col[N],tot,cap[N],tp,st[N];
struct Edge{ int to,nex; }edge[N<<1];
void addedge(int a,int b){
edge[nedge].to=b; edge[nedge].nex=hed[a]; hed[a]=nedge++;
}
void dfs(int k,int fa){
int nw=tp;
repedge(i,k){
int v=edge[i].to; if (v==fa) continue;
dfs(v,k);
if (tp-nw>=B){
cap[++tot]=k;
while (tp!=nw) col[st[tp--]]=tot;
}
}
st[++tp]=k;
}
int main(){
n=read(); B=read(); nedge=0; ms(hed,-1,hed);
rep(i,1,n-1){
int a=read(); int b=read();
addedge(a,b); addedge(b,a);
}
dfs(1,1);
while(tp) col[st[tp--]]=tot;
printf("%d\n",tot);
rep(i,1,n) if (i==n) printf("%d\n",col[i]); else printf("%d ",col[i]);
rep(i,1,tot) if (i==tot) printf("%d\n",cap[i]); else printf("%d ",cap[i]);
return 0;
}