zoukankan      html  css  js  c++  java
  • uva 11987 带删除操作的并查集与并查集的可持久化

    难点在于操作2,对于叶子结点而言,删除是很简单的,而对于根节点,删除好像是“不可能的”,所以我们可以在初始化的时候动一些脑筋,让每个结点最开始的父亲不是自己而是一个”虚节点(i+n)“,这样所有的结点都变成了叶子结点,然后问题就变得容易解决了。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 const int N = 200001;
     8 int f[N];
     9 ll sum[N];
    10 int num[N];
    11 int n, m;
    12 
    13 void init()
    14 {
    15     for ( int i = 1; i <= n; i++ )
    16     {
    17         f[i] = i + n;
    18     }
    19     for ( int i = n + 1; i <= 2 * n; i++ )
    20     {
    21         f[i] = i;
    22         sum[i] = i - n;
    23         num[i] = 1;
    24     }
    25 }
    26 
    27 int findf( int x )
    28 {
    29     if ( f[x] != x ) f[x] = findf( f[x] );
    30     return f[x];
    31 }
    32 
    33 void union_set( int x, int y )
    34 {
    35     x = findf(x), y = findf(y);
    36     if ( x != y )
    37     {
    38         f[x] = y;
    39         sum[y] += sum[x];
    40         num[y] += num[x];
    41     }
    42 }
    43 
    44 void move( int x, int y )
    45 {
    46     int fx = findf(x), fy = findf(y);
    47     sum[fx] -= x;
    48     num[fx]--;
    49     f[x] = fy;
    50     sum[fy] += x;
    51     num[fy]++;
    52 }
    53 
    54 int main ()
    55 {
    56     while ( scanf("%d%d", &n, &m) != EOF )
    57     {
    58         init();
    59         while ( m-- )
    60         {
    61             int op, p, q;
    62             scanf("%d", &op);
    63             if ( op == 1 )
    64             {
    65                 scanf("%d%d", &p, &q);
    66                 union_set( p, q );
    67             }
    68             else if ( op == 2 )
    69             {
    70                 scanf("%d%d", &p, &q);
    71                 move( p, q );
    72             }
    73             else
    74             {
    75                 scanf("%d", &p);
    76                 p = findf(p);
    77                 printf("%d %lld
    ", num[p], sum[p]);
    78             }
    79         }
    80     }
    81     return 0;
    82 }

    还有一种方法叫做”可持久化并查集“,随后补上。

  • 相关阅读:
    使用字符流(Writer、Reader)完成对文件的读写操作
    Java中File类重修
    适配器模式学习
    oracle 新建数据库 ,新建用户
    8.19 extjs jar 包使用。
    8.15 session 有效时间, session在数据查询中最后不用
    8.15 自定义tr行 滚动 信息行的滚动
    8.15jsp document 头部声明 区别
    8.14 图片滚动无缝
    8.13Oracle新建用户、角色,授权
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4752757.html
Copyright © 2011-2022 走看看