并查集
合并(merge)两个集合;查找某元素属于哪个集合或者不同元素是否在同一组
并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。
集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并。
并查集的基本操作有三个:
makeSet(s):建立一个新的并查集,其中包含 s 个单元素集合。
unionSet(x, y):把元素 x 和元素 y 所在的集合合并,要求 x 和 y 所在的集合不相交,如果相交则不合并。
find(x):找到元素 x 所在的集合的代表,该操作也可以用于判断两个元素是否位于同一个集合,只要将它们各自的代表比较一下就可以了。
void unite()
{
int fa = find(a);
int fb = find(b);
if (fa == fb)
return ;
if (ran[fa] < ran[fb]) //如果a树的深度小于b树 就把a树往b树上**合并**;
par[fa] = fb;
else
{
par[fb] = fa;
if (ran[fa] == ran[fb])
ran[fa]++;
}
}
const int maxn = 1e6 + 10;
int par[maxn];
void init(int n) //初始化
{
for (int i = 0; i <= n; i++)
par[i] = i;
}
压缩和不压缩的都要知道,后边有时会处理不压缩的;
int find(int x) //查找
{
1. if ( x!= par[x])
return /* par[x]=*/find(par[x]);
return x;
2. return x == par[x] ? x : /* */find(par[x]);
3. int q = x;
while (x != par[x])
x = par[x];
//上三种用于数据小的时候
/*
while (par[q] != x)
{
int j = par[q];
par[q] = x;
q = j;
} 数据较多 时第三种情况再加上这些
*/
return par[x];
}
void unite(int a, int b) //////
{
int fa = find(a);
int fb = find(b);
if (fa != fb)
par[fa] = fb; //将一个做另一个的父节点
}
int main()
{
return 0;
}
这篇博客讲的也很好:http://www.cnblogs.com/Yan-C/p/3943940.html
这个大佬讲的很有意思同样也很好,很生动http://blog.csdn.net/qq_34594236/article/details/51834882