【题意】
给定
N
个点的一棵树,要求将点划分成多个块,每个块
【数据范围】
1≤B≤N≤1000
【分析】
据说这就是把树分块的算法。
然而我是想看强制在线莫队才看这题的。
本题题解链接:
http://vfleaking.blog.163.com/blog/static/174807634201231684436977/)
时间复杂度:
O(n)
空间复杂度:
O(n)
【代码】
#include <cstdio>
#include <cctype>
const int N=1024;
int n,B;
struct Graph
{
int v,nxt;
}mp[N<<1];
int tt,hd[N];
inline int read(void)
{
int x=0,f=1; char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
inline void ins(int u,int v)
{
mp[++tt].v=v;
mp[tt].nxt=hd[u];
hd[u]=tt;
}
void init(void)
{
int u,v;
n=read(),B=read();
for (int i=1;i<n;i++)
{
u=read(),v=read();
ins(u,v),ins(v,u);
}
}
int stk[N],top;
int vis[N];
int own[N],cap[N],col;
void dfs(int now)
{
int bot=top;
vis[now]=1;
for (int k=hd[now];k;k=mp[k].nxt)
if (!vis[mp[k].v])
{
dfs(mp[k].v);
if (top-bot>=B)
{
cap[++col]=now;
for (;top!=bot;own[stk[top--]]=col);
}
}
stk[++top]=now;
}
void work(void)
{
dfs(1);
for (;top;own[stk[top--]]=col);
printf("%d\n",col);
for (int i=1;i<n;i++) printf("%d ",own[i]); printf("%d\n",own[n]);
for (int i=1;i<col;i++) printf("%d ",cap[i]); printf("%d\n",cap[col]);
}
int main(void)
{
init();
work();
return 0;
}
【小结】树分块的方法。