并查集(路径压缩)
并查集(路径压缩)
http://hi.baidu.com/mfs666/blog/item/6069b6197fbbb44243a9ada7.html
并查集的作用就是将一堆元素两两间的联系情况来统计和查询元素间的集合关系
这是最普通的版本,没有启发式合并,不支持关系的删除和有序的合并(银河英雄传说那种)
并查集的应用:除了定义上的应用,目前知道的应用有:图中加边判断环(本来是一种最小生成树算法,但可以是动态的加入边),快速判断是否已经连通(只有一个集合)
program findset;
var
f:array[1..100000] of longint;
i,n,nn,nnn,a,b,c:longint;
function find(x:longint):longint;//查集
begin
if f[x]=x then begin//已经找到总根,推出
find:=x;
exit;
end;
find:=find(f[x]);//不是总根,继续找它的根的根
f[x]:=find;//路径压缩,简单而重要的一句
end;
procedure com(x,y:longint);//并集
var
fx,fy:longint;
begin
fx:=find(x);
fy:=find(y);
if fx<>fy then// 总根不是同一个
f[fx]:=fy; 将一个的总根的根设为另一个的总根,保证只有一个总根
end;
begin
readln(n,nn,nnn);
for i:=1 to n do
f[i]:=i;
for i:=1 to nn do begin
readln(a,b);
com(a,b);
end;
for i:=1 to n do
if find(i)=i then
inc(c);
writeln(c);
for i:=1 to nnn do begin
readln(a,b);
if find(a)=find(b) then
writeln(true)
else
writeln(false);
end;
end.