一、并查集
1、初始化
//初始化n个元素
void init(int n)
{
for(int i=0; i<n; i++)
{
par[i] = i;
rank[i] = 0;
}
}
2、查询到一个点的根
int find(int x)
{
if(par[x] == x)
return x;
else
{
return par[x] = find(par[x]);
}
}
3、在2中,如果因为数据极端,并查集就会退化成一个链,如果加入路径压缩,并查集算法才会更高效。
int find(int x)//递归写法;
{
if(par[x] == x)
return x;
par[x] = find(par[x]);
return find(par[x]);
}
int find(int x)//非递归写法(更好)
{
int root = x;
while(root!=par[root])//先找到根节点r;
{
root = par[root];
}
int y = x;
while(y!=root)
{
int fath = par[y];
par[y] = root;
y = fath;
}
return r;
}
4、合并
void unite(int x, int y)
{
int xx = find(x);
int yy = find(y);
if(x!=y)
{
par[xx] = yy;
}
}
二、带权并查集
带权值的并查集在并查集中加入了value[ ]数组,value可以记录很多东西,不限制于距离等,还可以是相对根节点的状态等。加入了权值,函数会有改变。
int find(int x)
{
if(par[x]==x)
return x;
int tmp = par[x];
par[x] = find(par[x]);
value[x] = value[tmp]+1;
return par[x];
}