- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
并查集及应用
并查集及应用
在信息学竞赛中,并查集是一种不可忽视的一部分内容,把最近几年的NOI和NOIP复赛题目大致浏览了一遍,发现有好几道应用并查集的题目,因此本文由浅入深的介绍并查集在编程中的巧妙应用。
什么是并查集?并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。集就是让每个元素构成一个单元素的集合,并就是按一定顺序将属于同一组的元素所在的集合合并。
并查集的主要操作:
这就是说,我们在“合并5和3”的时候,不是简单地将5的父亲指向3,而是直接指向根节点1,由此我们得到了一个复杂度只是O(1)的算法。
〖程序清单〗
(1)初始化:
for i:=1 to n do father[i]:=i;
因为每个元素属于单独的一个集合,所以每个元素以自己作为根结点。
(2)寻找根结点编号并压缩路径:
function getfather(v : integer) : integer;
begin
if father[v]=v then exit(v);
father[v]:=getfather(father[v]);
getfather:=father[v];
end;
(3)合并两个集合:
proceudre merge(x, y : integer);
begin
x:=getfather(x);
y:=getfather(y);
father[x]:=y;
end;
(4)判断元素是否属于同一集合:
function judge(x, y : integer) : boolean;
begin
x:=getfaher(x);
y:=getfather(y);
if x=y then exit(true)
else exit(false);
end;
faher[1]:=1;faher[2]:=1;faher[3]:=1;faher[4]:=5;faher[5]:=3
至此,我们用上述的算法已经解决了空间的问题,我们不再需要一个n2的空间来记录整张图的构造,只需要用一个记录数组记录每个结点属于的集合就可以了。
但是仔细思考不难发现,每次询问两个元素是否属于同一个集合我们最多还是需要O(n)的判断!
参考程序:
var father:array[1..5000]of integer;
i,j,k,p,n,m:integer;
Function getfather(v:integer):integer;
begin
if father[v]=v then exit(v);
father[v]:=getfather(father[v]);
getfather:=father[v];
end;
Procedure merge(x,y:integer);
begin
x:=getfather(x);
y:=getfather(y);
father[x]:=y;
end;
Function judge(x,y:integer):boolean;
begin
x:=getfather(x);
y:=getfather(y);
If x=y then exit(true) else exit(false);
end;
begin
readln(n,m,p);
for i:=1 to n do father[i]:=i;
for i:=1 to m do
begin
read(j,k);
merge(j,k);
end;
for i:=1 to p do
begin
read(j,k);
if judge(j,k) then writeln(Yes) else writeln(No);
end;
end.
例2:mty的考验(RQNOJ343)
啊!几经周折.mty终于找到了他的偶像.他就是....fyc!
可是fyc这样的高级人士可不喜欢一个人总是缠着他.于是他出了一道难题想考考mty.fyc有几个手下:陈乐天,舒步鸡,胡巍......现在fyc要去和别人fight,需要组建一值军队.军队的士兵在fyc的手下里选.
要组建一个军队,必修满足军队中的每个人之间都有直接或间接的朋友关系.
那么mty现在需要组建一支在满足上述情况下的人数最多的军队.
1=n=1000,1=m=500.
【输入格式】第一行,两个数,n,m.(n表示fyc有几个手下m表示有m对朋友关系).一下m行,每行两个数.x[i],y[i].表示编号为x[i]
原创力文档


文档评论(0)