void makeset(int parent[],int rank[],int n)
{
int i;
for(i=0;i<n;++i)
{
parent=i;
rank=0;
}
}
int findset(int parent[],int i)
{
int temp,j;
j=i;
while(j!=parent[j])
j=parent[j];
while(i!=parent)
{
temp=parent;
parent=j;
i=temp;
}
return j;
}
void unionset(int parent[],int rank[],int i,int j)
{
i=findset(parent,i);
j=findset(parent,j);
if(i!=j)
{
if(rank>rank[j])
parent[j]=i;
else
{
parent=j;
if(rank==rank[j])
++rank[j];
}
}
}
并查集是一种很基本的数据结构,可我以前竟不知道。最近做pku的acm online judge题遇到了,用起来很顺手,觉得这是一种很有用有数据结构。
并查集是一种可以方便地进行以下三种操作的数据结构:
合并两个集合;将一元素并入另一集体;判断两个元素是否属于同一个集合。
例如,可以用数组很方便地实现一个并查集,对一个含有n个元素的并查集,可以用一个长度为n的数组实现,主要设计以下四种操作:
初始化并查集:每个元素赋一不同的值,时间复杂度为O(n)。
合并两个集合A和B:将所有标记为B集体的元素的标记变为A集体的标记,时间复杂度为O(n)。
将一元素a并入集合A:时间复杂度为O(1)。
判断两元素是否属于同一集体:只须比较标记,时间复杂度为O(1).
并查集的定义并查集是一种简单的集合,它支持三种操作: MakeSet(x):创建一个只包含一个元素x的并查集 Find(x, S):判断x是否在集合S中 Union(A, B):合并两个并查集A和B 并查集与树可以将每一棵树都看成是元素的集合,从而可以用树来表示并查集. 1 4 2 5 6 3 7 MakeSet 一个元素可以看成是只有根结点的树 1 Find 判断一个元素x是否在并查集S中,只需找到x的根结点,看它是否等于S的根结点 1 4 2 5 6 3 7 Union 合并两个并查集,只需把其中一个根结点变成另一个根结点的儿子即可 1 4 2 6 3 用数组表示树 1 4 2 5 6 3 7 5 2 1 1 2 1 0 7 6 5 4 3 2 1 父亲表示法用数组表示森林 1 4 2 5 6 3 7 5 2 0 1 2 0 0 7 6 5 4 3 2 1 父亲表示法并查集常用的数据结构我们一般对所有的元素从1到n编号,这样我们就可以用元素的编号来表示这个元素.同时使用一个数组来存放相应的并查集. 我们用树的根结点来表示整棵树,即整个集合.