- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 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)
您可能关注的文档
- 根性腰痛针灸治疗.doc
- 2010全国自学考试工程地质与土力学真题及答案.doc
- 英国科技与文化作业.doc
- 专题九 欧美资产阶级革命(世界近代政治).ppt
- 寓教于游戏之中.doc
- Android彻底退出应用程序.doc
- 第二章 运行和配置IOS(4课时).doc
- 二1-12050工作面采后总结.doc
- 培训汇总之企业培训师10种个人素质.doc.pdf
- 管理制度20110425.doc
- 2025年中国锻铁围栏市场调查研究报告.docx
- 2025年中国椭圆型市场调查研究报告.docx
- 2025年中国无蔗糖原味豆浆市场调查研究报告.docx
- 2025-2031年中国泛在电力物联网行业发展运行现状及投资潜力预测报告.docx
- 2025年中国制袋机零件市场调查研究报告.docx
- 2025年中国智能除垢型电子水处理仪市场调查研究报告.docx
- 2025-2031年中国甘肃省乡村旅游行业市场深度研究及投资策略研究报告.docx
- 2025-2031年中国干海产品行业市场发展监测及投资战略规划报告.docx
- 2025年中国全铝图解易拉盖市场调查研究报告.docx
- 2025年中国人造毛皮服装市场调查研究报告.docx
文档评论(0)