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 ",ans); } return 0; }