一.初始化init()
void init()
{
for(i=1;i<=n;i++)
{
father[i]=i;
num[i]=1; //用于求处在同一个集合里的元素个数;
}
}二.查找find()
方法一:
int find(int t)
{
int x;
x=t;
while(father[x]!=x) x=father[x]; //找到祖先节点;
int y,i;
i=t;
while(father[i]!=x) //路径压缩;
{
y=father[i];
father[i]=x;
i=y;
}
return x;
}
方法二:
int find(int x){
if(x==father[x]) return x;
father[x] = find(father[x]);
return father[x];
}
例如杭电3635,必须要用方法二来求移动次数;三.合并unin()
void unin(int u,int v)
{
u=find(u);
v=find(v);
v=father[u]; //一般来说,u和v顺序无所谓,但是有些并查集的变形需要注意一下顺序;
num[v]+=num[u]; //统计相同集合元素的个数;
}
四.其他
father[i]相同的点在一起;
当father[i]==i时可以当做一个集合的代表;
统计father[i]==i的个数就可以求出集合的个数;
五.并查集扩展
3938 离线并查集
2473 并查集删除,马甲
3635 每个点的移动次数

被折叠的 条评论
为什么被折叠?



