并查集
int a[10005];
初始化
for(int i=1;i<=10005;i++)
{
a[i]=i;
}
查找
## 非递归
int find(int x)
{
while(x!=a[x])
{
x=a[x];
}
return x;
}
## 递归
int find(int x)
{
if(x==a[x])
{
return x;
}
else return find(a[x]);
}
一般合并
void union(int x,int y)
{
if(find(x)!=find(y))
{
a[x]=y;
}
}
按秩合并
按树高
void un(int x,int y)
{
//a[x]=-树高!!!
if(a[x]>a[y])
{
a[x]=y;
}
else
{
if(a[x]==a[y])
{
a[x]–;
}
a[y]=x;
}
}
按规模
void un(int x,int y)
{
a[x]=-元素个数
if(a[x]<a[y])
{
a[y]=a[y]+a[x];
a[x]=y;
}
else
{
a[x]=a[x]+a[y];
a[y]=x;
}
}
压缩路径
递归
int yasuo(int x)
{
if(a[x]<0)
{
return x;
}
else
return a[x]=yasuo(a[x]);
}
非递归
int find(int x)
{
int k, j, r;
r = x;
while(r != parent[r]) //查找跟节点
r = a[r]; //找到跟节点,用r记录下
k = x;
while(k != r) //非递归路径压缩操作
{
j = a[k]; //用j暂存a[k]的父节点
a[k] = r; //a[x]指向跟节点
k = j; //k移到父节点
}
return r; //返回根节点的值
}