cogs 2039. 树的统计

2039. 树的统计

★★   输入文件:counttree.in   输出文件:counttree.out   简单对比
时间限制:1 s   内存限制:128 MB

【题目描述】

关于树的统计问题有多种多样的版本,这里你需要解决一个比较简单的问题:对于一棵包含N个节点的有根树,将所有点从1到N编号后,对于每一个节点v,统计出以v为根的子树中有多少个点的编号比v小。

 

【输入格式】

输入第一行包含一个整数N,以下N行每行包含一个整数,其中第i行的整数表示编号为i的节点的父亲节点的编号,根的父亲节点编号为0。

【输出格式】

输出包含N行,其中第i行给出编号为i的节点的统计结果。

【样例输入】

3
2
3
0

【样例输出】

0 1 2

【提示】

在此键入。

【来源】

20%的数据1<=n<=1000

100%的数据1<=n<=100000

 

这题可以用循环水过的

我用的dfs序

#include<cstdio>
#include<vector>
using namespace std;
 
const int N=100003;
vector<int>vec[N];
int n,a;
int read(){
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
    return x*f;}
 
int num=0;
int head[N];
int tail[N];
int dfsx[N];
 
 
 
void dfs(int root)
{
    dfsx[++num]=root;head[root]=num;
    for(int i=0;i<vec[root].size();i++)
    {
        dfs(vec[root][i]);
    }
    tail[root]=num;
}
 
int main()
{
    freopen("counttree.in","r",stdin);
    freopen("counttree.out","w",stdout);
    n=read();
    int r;
    for(int i=1;i<=n;i++)
    {
        a=read();
        if(a==0)
        r=i;
        vec[a].push_back(i);
    }
    dfs(r);
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        ans=0;
        for(int j=head[i]+1;j<=tail[i];j++)
        {
            if(i>dfsx[j])ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2017-06-13 09:08  zzzzx  阅读(158)  评论(0编辑  收藏  举报