题解:

树分块

每一次当个数大于B的时候分成一块

省会城市为当前子树根

然后最后剩下的节点和前一个分为一块

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int ne[N],num,top,x,y,root[N],fi[N],zz[N],st[N],be[N],cnt,n,m;
int jb(int x,int y)
{
    ne[++num]=fi[x];
    fi[x]=num;
    zz[num]=y;
}
void dfs(int x,int y)
{
    int now=top;
    for (int i=fi[x];i;i=ne[i])
     if (zz[i]!=y)
      {
          dfs(zz[i],x);
          if (top-now>=m)
           {
               root[++cnt]=x;
               while (top!=now)be[st[top--]]=cnt;
         }
      }
    st[++top]=x;  
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<n;i++)
     {
         scanf("%d%d",&x,&y);
         jb(x,y);jb(y,x);
     }
    dfs(1,0);
    while (top)be[st[top--]]=cnt;
    printf("%d\n",cnt);
    for (int i=1;i<=n;i++)printf("%d ",be[i]);
    puts("");
    for (int i=1;i<=cnt;i++)printf("%d ",root[i]);
}

 

posted on 2018-02-21 11:16  宣毅鸣  阅读(...)  评论(... 编辑 收藏