码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1086 [SCOI2005]王室联邦 ——DFS

时间:2017-03-24 21:44:08      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:bzoj   序列   iostream   lin   cstring   上传   style   mem   cpp   

手把手教你树分块系列。

只需要记录一个栈,如果等于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‘:‘ ‘);
}

  妈妈,我会树分块辣~\(≧▽≦)/~啦啦啦!

BZOJ 1086 [SCOI2005]王室联邦 ——DFS

标签:bzoj   序列   iostream   lin   cstring   上传   style   mem   cpp   

原文地址:http://www.cnblogs.com/SfailSth/p/6613536.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!