博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法模板——并查集 2(支持快速即时查询本连通块内容,纯原创!)
阅读量:6330 次
发布时间:2019-06-22

本文共 2317 字,大约阅读时间需要 7 分钟。

实现功能:输入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 var11    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           begin17                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          begin23               if x<>c[x] then c[x]:=getfat(c[x]);24               exit(c[x]);25          end;26 begin27      readln(n);28      for i:=1 to n do29          begin30               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 do35            begin36                 read(l);37                 case l of38                      1:begin39                             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:begin46                             readln(j);47                             j:=getfat(j);48                             p:=a[j].he;49                             while p<>nil do50                                   begin51                                        write(p^.g,' ');52                                        p:=p^.next;53                                   end;54                             writeln;55                      end;56                 end;57 58            end;59 end.

 

转载于:https://www.cnblogs.com/HansBug/p/4293503.html

你可能感兴趣的文章
字符串格式化
查看>>
Why Should You Choose Linux?
查看>>
NetScaler 12.1 发布
查看>>
checkpoint system management
查看>>
CentOS 6.5安全加固及性能优化_操作系统
查看>>
每天laravel-20160709|CallEvent
查看>>
我的友情链接
查看>>
【三石jQuery视频教程】02.创建 FontAwesome 复选框和单选框
查看>>
Cisco 配置DHCP中继 代理工程 实例
查看>>
Centos7.3部署KVM虚拟化环境
查看>>
configure: error: Cannot find ldap.h
查看>>
Linux启动分析(2)— bootsect.S、setup.S、head.S分析
查看>>
自学java时的笔记(一)
查看>>
Qt之文本编辑器(二)
查看>>
python编译时检查语法错误
查看>>
考题纠错2
查看>>
SQL——索引
查看>>
Python新手快速入门教程-基础语法
查看>>
JVM性能调优入门
查看>>
关于raid的基本原理、软raid的实现演示
查看>>