手把手教你树分块系列。
只需要记录一个栈,如果等于B的情况就弹栈,令省会为当前节点。
然后把待分块的序列不断上传即可。
考虑到有可能弹出不是自身节点的子树节点,所以记录一下当前的栈底。
DFS即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 2005
#define F(i,j,k) for (int i=j;i<=k;++i)
int h[maxn],to[maxn],ne[maxn],en=0;
void add(int a,int b)
{to[en]=b;ne[en]=h[a];h[a]=en++;}
int n,b,sta[maxn],top,bel[maxn],cnt,rt[maxn];
void dfs(int o,int fa)
{
int nbot=top;
// printf("dfs on %d %d\n",o,nbot);
for (int i=h[o];i>=0;i=ne[i])
if (to[i]!=fa){
dfs(to[i],o);
if (top-nbot>=b)
{
// printf("top is %d nbot is %d\n",top,nbot);
rt[++cnt]=o;
while (top!=nbot)
{
// printf("pop\n");
bel[sta[top--]]=cnt;
}
}
}
sta[++top]=o;
}
int main()
{
memset(h,-1,sizeof h);
scanf("%d%d",&n,&b);
F(i,1,n-1)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs(1,0);
while (top) bel[sta[top--]]=cnt;
printf("%d\n",cnt);
F(i,1,n) printf("%d%c",bel[i],i==n?'\n':' ');
F(i,1,cnt) printf("%d%c",rt[i],i==cnt?'\n':' ');
}
妈妈,我会树分块辣~\(≧▽≦)/~啦啦啦!