NOCOW_并查集.docVIP

  1. 1、本文档共5页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
NOCOW_并查集

并查集 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。 [编辑] 并查集的主要操作 合并两个不相交集合 判断两个元素是否属于同一集合 [编辑] 主要操作的解释及代码 需要注意的是,一开始我们假设元素都是分别属于一个独立的集合里的。 (1) 合并两个不相交集合操作很简单:先设置一个数组Father[x],表示x的“父亲”的编号。那么,合并两个不相交集合的方法就是,找到其中一个集合最父亲的父亲(也就是最久远的祖先),将另外一个集合的最久远的祖先的父亲指向它。 附图一张(摘自CLRS)——Ronice a图为两个不相交集合,b图为合并后Father(b):=Father(g) 代码: Procedure Union(x,y:integer);{其中GetFather是下面将讲到的操作} var fx,fy?: integer; begin fx?:= GetFather(x); fy?:= GetFather(y); If fxfy then Father[fx]?:= fy;{指向最祖先的祖先} end; (2) 判断两个元素是否属于同一集合仍然使用上面的数组。则本操作即可转换为寻找两个元素的最久远祖先是否相同。可以采用递归实现。(有待补图,制作中)代码: Function Same(x,y:integer):boolean; begin if GetFather(x)=GetFather(y) then exit(true) else exit(false); end; [编辑] 并查集的优化 (1)路径压缩 刚才我们说过,寻找祖先时采用递归,但是一旦元素一多起来,或退化成一条链,每次GetFather都将会使用O(n)的复杂度,这显然不是我们想要的。 对此,我们必须要进行路径压缩,即我们找到最久远的祖先时“顺便”把它的子孙直接连接到它上面。这就是路径压缩了。使用路径压缩的代码如下,时间复杂度基本可以认为是常数的。 附图摘自CLRS: Procedure Initialize; var i:integer; begin for i:=1 to maxv do Father[i]:=i; end; ? Function GetFather(v:integer):integer; begin if Father[v]=v then exit(v) else Father[v]:=GetFather(Father[v]); exit(Father[v]); end; (2)rank合并 合并时将元素少的集合合并到元素多的集合中。 function judge(x,y:integer):boolean; var fx,fy?: integer; begin fx?:= GetFather(x); fy?:= GetFather(y); If fx=fy then exit(true) else judge?:= false; if rank[fx]rank[fy] then father[fy]?:= fx else begin father[fx]?:= fy; if rank[fx]=rank[fy] then inc(rank[fy]); end; end; 初始化:fillchar(rank,sizeof(rank),0); [编辑] 时间复杂度 O(n*α(n)) 其中α(x),对于x=宇宙中原子数之和,α(x)不大于4 事实上,路经压缩后的并查集的复杂度是一个很小的常数。 [编辑] 源代码 加了所有优化的代码框架: c c++ Code:Disjointset c++ 来自NOCOW 跳转到: 导航, 搜索 #includeiostream #define MAXN 100001 using namespace std; ? int father[MAXN],n,m,q; ? int getfather(int v){ if (father[v]==v) return v; father[v]=getfather(father[v]); return father[v]; } ? bool same(int x,int y){ return (getfather(x)==getfather(y)

文档评论(0)

qwd513620855 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档