• 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

    暴力,找出所有最底下的点(也就是叶节点),有叶节点往上不断找到祖先,如果祖先的序号比他小,那么祖先这个点的ans就++,找这个点时可以用拓扑排序。

     1 #include<cstdio>
     2 #include<queue>
     3 using namespace std;
     4  
     5 const int N = 100100;
     6  
     7 queue<int>q;
     8 int fa[N];    //记录父亲 
     9 int ans[N];    
    10 int ru[N];    //记录入度 
    11 int n,d,now;
    12  
    13 void sove()
    14 {
    15     for(int i=1;i<=n;++i)
    16         if(ru[i]==0) q.push(i);
    17     while(!q.empty())
    18     {
    19         d = q.front();
    20         q.pop();
    21         now = d;
    22         while(fa[now])
    23         {
    24             now = fa[now];
    25             if(d < now) ans[now]++;
    26         }
    27         ru[fa[d]]--;
    28         if(ru[fa[d]]==0) q.push(fa[d]);
    29     }
    30 }
    31  
    32 int main()
    33 {
    34     freopen("counttree.in","r",stdin);
    35     freopen("counttree.out","w",stdout);
    36     scanf("%d",&n);
    37     for(int i=1;i<=n;++i)
    38     {
    39         scanf("%d",&fa[i]);
    40         ru[fa[i]]++;
    41     }
    42     sove();
    43     for(int i=1;i<=n;++i)
    44         printf("%d
    ",ans[i]);
    45     return 0;
    46 }
  • 相关阅读:
    剑指Offer:面试题17——合并两个排序的链表
    剑指Offer:面试题16——反转链表(java实现)
    剑指Offer:面试题15——链表中倒数第k个结点(java实现)
    Timer和TimerTask 定时器和定时任务
    Spring-WebSocket 教程
    单点登录原理与简单实现
    Python机器学习:泰坦尼克号获救预测一
    转 smarty学习笔记电子版整理
    转 nodejs socket.io初探
    html5新增的属性和废除的属性
  • 原文地址:https://www.cnblogs.com/mjtcn/p/6912909.html
Copyright © 2020-2023  润新知