HDOJ 3887-DFS人工スタック、ツリー配列

1884 ワード

/* 
    。dfs   ,      x    sum(x-1),  add  ,      x     sum(x-1) 
        sum        x     
            ,        ,   while+          ,  c++        ,        
           ~~           。
*/  
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

const int NN=100010;

vector<int> v[NN];
int n,r;
int s[NN],c[NN],cur[NN],pre[NN];
bool vis[NN];

int lowbit(int x)
{
    return x&(-x);
}

void update(int x,int w)
{
    while (x<=n)
    {
        c[x]+=w;
        x+=lowbit(x);
    }
}

int getsum(int x)
{
    int ret=0;
    while (x)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}

int ss[NN],top;
void dfs()
{
    ss[top=1]=r;
    pre[r]=0;
    vis[r]=true;
    update(r,1);
    while (top)
    {
        int x=ss[top];
        for (int &i=cur[x]; i<v[x].size(); i++)
        {
            int y=v[x][i];
            if (!vis[y])
            {
                vis[y]=true;
                pre[y]=getsum(y-1);
                update(y,1);
                ss[++top]=y;
                break;
            }
        }
        if (cur[x]==v[x].size())
        {
            s[x]=getsum(x-1)-pre[x];
            top--;
        }
    }
}

int main()
{
    while (scanf("%d%d",&n,&r)!=EOF && n|r)
    {
        for (int i=1; i<=n; i++)
        {
            v[i].clear();
            c[i]=0;
            s[i]=0;
            vis[i]=false;
            cur[i]=0;
        }
        int x,y;
        for (int i=1; i<n; i++)
        {
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        dfs();
        printf("%d",s[1]);
        for (int i=2; i<=n; i++) printf(" %d",s[i]);
        printf("
"); } return 0; }