您的位置:首页 > 其它

并查集模板

2017-08-03 10:36 211 查看
#include <stdio.h>

/*有的写法用到了树的深度,就是重新开一个数组ran[maxn];
用来记录每个树的深度,合并的时候把深度较小的合并到较大的上边,防止出现最极端的情况。
但是用上路径压缩的话就不需要这个数组,因为压缩过后深度都是 2 ,随意操作;
压缩就是把/* *//*里面的 par[x] = 加上,不加上去的话只查找,没有压缩;
附上带ran[]数组的合并;
如果用ran[]数组,尽量不要用rank[] rank再后边学习的时候是一个关键字; */
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 /* */find(par[x]);
return x;

法2. return x == par[x] ? x : /* */find(par[x]);

法3. int p = x, 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: