zoukankan      html  css  js  c++  java
  • LA3027简单带权并查集

    题意:
          有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少?


    思路:
         可以直接简单带权并查集就能搞定,核心代码是这样,设s_x[i]表示i到自己父亲节点的距离,然后
    //处理并查集的时候
    int finds(int x)
    {
      if(x == mer[x]) return x;
      int k = mer[x];
      mer[x] = finds(mer[x]);
      mer[x] += mer[k];
      return mer[x];
    }


    //建立关系的时候


    mer[a] = b;
    s_x[a] = abs(a - b) % 1000


    //询问的时候
    x = finds(a);//这一部别忘记了,因为并查集用了路径压缩,查询一次之后才能更新到他到根的距离,不然后可能只是他到他上一个节点的距离,查询后经过路径压缩会把他上一个节点变成他的根节点。
    printf(s_x[a]);








    #include<stdio.h>
    #include<string.h>


    #define N 22000


    int mer[N] ,s_x[N];


    int abss(int x)
    {
       return x > 0 ? x : -x;
    }


    int finds(int x)
    {
        if(x == mer[x]) return x;
        int k = mer[x];
        mer[x] = finds(mer[x]);
        s_x[x] =(s_x[x] + s_x[k]);
        return mer[x];
    }


    int main ()
    {
        int t ,n ,a ,b;
        char str[5];
        scanf("%d" ,&t);
        while(t--)
        {
           scanf("%d" ,&n);
           for(int i = 0 ;i <= n ;i ++)
           mer[i] = i ,s_x[i] = 0;
           while(~scanf("%s" ,str) && str[0] != 'O')
           {
              if(str[0] == 'I')
              {
                 scanf("%d %d" ,&a ,&b);
                 mer[a] = b;
                 s_x[a] = abss(a - b) % 1000;
              }
              else
              {
                   scanf("%d" ,&a);
                   finds(a);
                   printf("%d " ,s_x[a]);
              }
           }
        }
        return 0;
    }



  • 相关阅读:
    四级英语day9
    123
    像程序员一样思考
    Kali
    OS X
    Effective Java
    DHU ACM OJ
    Ambari
    Hadoop
    Hadoop2
  • 原文地址:https://www.cnblogs.com/csnd/p/12062563.html
Copyright © 2011-2022 走看看