zoukankan      html  css  js  c++  java
  • AOJ 2170 Marked Ancestor (基础并查集)

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=45522

    给定一棵树的n个节点,每个节点标号在1到n之间,1是树的根节点,有如下两种操作:

    M v :把编号为v的节点标记。

    Q v :查询与v节点距离最近的被标记的点的编号。最初只有根节点被标记。

    输入n-1个数表示,每一个数是当前第i个数的父节点,输出对于每个查询得到标号的总和。

    并查集与树的结合,在输入的时候就可以根据父节点的关系建立并查集,1的父亲是1.

    还有把编号为v的节点标记的意思是等同于把这颗子树从并查集里面分出来。因为只要这个节点被标记,那么他的字节点一定是到这个节点的距离最小。

    理解清楚这题就很简单,只涉及到查找这个操作。注意sum可能溢出。

     1 #include<cstdio>
     2 int par[100010];
     3 int find(int x)
     4 {
     5     if(x==par[x]) return x;
     6     return find(par[x]);
     7 }
     8 int main()
     9 {
    10     int n,q,a,b;
    11     while(~scanf("%d%d",&n,&q))
    12     {
    13         if(n==0&&q==0) break;
    14         for(int i=2;i<=n;i++)
    15         {
    16             scanf("%d",&par[i]);
    17         }
    18         par[1]=1;
    19         long long sum=0;
    20         char s[5];
    21         while(q--)
    22         {
    23             scanf("%s%d",s,&b);
    24             if(s[0]=='Q') sum+=find(b);
    25             else if(s[0]=='M') par[b]=b;  //分离 b节点
    26         }
    27         printf("%lld
    ",sum);
    28     }
    29     return 0;
    30 }
  • 相关阅读:
    linux-满足多字符条件统计行数
    oracle的面试问题
    在开发过程中为什么需要写存储过程
    面向对象编程
    动态SQL
    触发器

    子程序
    游标
    集合
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4491903.html
Copyright © 2011-2022 走看看