zoukankan      html  css  js  c++  java
  • 算法模板——并查集 2(支持快速即时查询本连通块内容,纯原创!)

    实现功能:输入N,现在有N个数;接下来输入任意行,如果是"1 x y"则表示把x和y所在的块合并;如果是"2 x"则表示输出x所在的块的全部内容

    原理:其实主要是自己创造了一个可并链line,he表示链头,ta表示链尾,然后对于不同块之间的合并就是直接把两条链对接,也就是一个的尾巴接到另一个的头上,构成新链(由于是链的直接叠加,所以可以做到严格的O(1),并且输出时输出多少复杂度就是多少,完全不存在额外复杂度)。然后同时用原本的普通数组并查集进行维护和追踪(理论值为O(logn)但实际上由于c[x]:=getfat(c[x])的优化导致实际测试结果远远小于这一复杂度)

    复杂度:【合并操作O(1),查询O(块大小)(意味着复杂度几乎完全用来输出)】×N,相比于之前的算法对于即时处理的性能有所提高,但是只需要最终进行静态的全局处理时,两者差不太多,这个会略快些,传统程序代码略少些

    (PS:值得注意的是,这种新的数据结构中千万要特判两个数字处于同一块的情况,必须避免同一条链首尾相接导致产生环!!!本程序41行continue那里有所体现。同时c[x]:=y之类的合并块语句以及merge(x,y)操作是有顺序之分的,两者顺序必须保持一致,不想原来的并查集顺序任意)

     1 type
     2     point=^node;
     3     node=record
     4                g:longint;
     5                next:point;
     6     end;
     7     line=record
     8                he,ta:point;
     9     end;
    10 var
    11    a:array[0..100000] of line;
    12    c:array[0..100000] of longint;
    13    i,j,k,l,m,n:longint;
    14    p:point;
    15 procedure merge(var p1,p2:line);inline;
    16           begin
    17                p1.ta^.next:=p2.he;
    18                p1.ta:=p2.ta;
    19                p2.he:=nil;p2.ta:=nil;
    20           end;
    21 function getfat(x:longint):longint;inline;
    22          begin
    23               if x<>c[x] then c[x]:=getfat(c[x]);
    24               exit(c[x]);
    25          end;
    26 begin
    27      readln(n);
    28      for i:=1 to n do
    29          begin
    30               c[i]:=i;
    31               new(p);p^.g:=i;p^.next:=nil;
    32               a[i].he:=p;a[i].ta:=p;
    33          end;
    34      while true do
    35            begin
    36                 read(l);
    37                 case l of
    38                      1:begin
    39                             readln(j,k);
    40                             j:=getfat(j);k:=getfat(k);
    41                             if j=k then continue;
    42                             c[k]:=j;
    43                             merge(a[j],a[k]);
    44                      end;
    45                      2:begin
    46                             readln(j);
    47                             j:=getfat(j);
    48                             p:=a[j].he;
    49                             while p<>nil do
    50                                   begin
    51                                        write(p^.g,' ');
    52                                        p:=p^.next;
    53                                   end;
    54                             writeln;
    55                      end;
    56                 end;
    57 
    58            end;
    59 end.         
  • 相关阅读:
    [Linux]
    [Nginx]
    [Nginx]
    [Linux]
    [Linux]
    [Linux]
    [Linux]
    [Linux] -Docker修改空间大小
    [Linux]
    [MySql]
  • 原文地址:https://www.cnblogs.com/HansBug/p/4293503.html
Copyright © 2011-2022 走看看