按秩合并
矮树合并到高树
void Union(int a, int b)
{
if(tree[a].weight == tree[b].weight) {
tree[b].parent = a;
tree[a].weight += 1;
}
else if (tree[a].weight > tree[b].weight) {
tree[b].parent = a;
}
else {
tree[a].parent = b;
}
}
将查找到的节点均指向根节点
递归
int Find(int x)
{
if(root[x] == -1)
{ return x; }
return root[x] = Find(root[x]);
}
非递归
int Find (int n)
{
int r = n;
while (r != root[r])
{
r = root[r];
}
int x = n, y;
while (x != r) { //压缩路径,全部赋值为根结点的值
y = root[x];
root[x] = r;
x = y;
}
return r;
}
例题 HDU 1856 http://acm.hdu.edu.cn/showproblem.php?pid=1856
#include <stdio.h>
#define maxn 10000005
struct Node{
int m;
int rank;
}tree[maxn];
int mm,pre[maxn];
int Find(int x)
{
int p = x;
while(tree[p].m != p)
{
p = tree[p].m;
}
int i = x;
while(i != p)
{
int j = tree[i].m;
tree[i].m = p;
i = j;
}
return p;
}
int hb(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
tree[fy].rank+= tree[fx].rank;
if(tree[fy].rank>mm)
mm=tree[fy].rank;
tree[fx].m=fy;
}
}
int main()
{
int t,i;
int x,y;
while(~scanf("%d",&t))
{
mm=1;
for(i=0;i<t;i++)
{
tree[i].m=i;
tree[i].rank=1;
}
for(i=0;i<t;i++)
{
scanf("%d%d",&x,&y);
hb(x,y);
}
printf("%d\n",mm);
}
}