//并查集
#include<stdio.h>
int MaxSize;
typedef int Elemtype;
typedef struct{
Elemtype data;
int parent;
}SetType;
//并查集查找
int Find(SetType s[],Elemtype x)
{//MaxSize是全局变量,代表着并查集的大小
int i;
for(i=0;i<MaxSize&&s[i].data!=x;i++)//查找x
if(i>=MaxSize) return -1; //此条件下代表没找到,返回-1
for(;s[i].parent>=0;i=s[i].parent); //因为根结点的parent是负数,所以一旦不符合条件退出循环,那么此时的i必是根结点的下标
return i;
}
//合并
void Union(SetType s[],Elemtype x1,Elemtype x2)
{
int root1,root2;
root1=Find(s,x1);//查找x1元素的根结点
root2=Find(s,x2);//查找x1元素的根结点
if(root1!=root2){//如果根结点不同,则合并
s[root1].parent+=s[root2].parent;//当合并后,根结点的parent存储的是合并后树元素的个数的负数
if(s[root1].parent<s[root2].parent) s[root2].parent=root1;//把个数较少的树接到个数较多的树上,这样使树平衡一点,加快查找效率
else s[root1].parent=root2;//同理
}
}
int main()
{
SetType s[100];
scanf("%d",&MaxSize);
for(int i=0;i<MaxSize;i++){
scanf("%d",&s[i].data);
s[i].parent=-1;
}
Elemtype x1,x2;
while(scanf("%d%d",&x1,&x2)&&x1)
Union(s,x1,x2);
for(int i=0;i<MaxSize;i++)
printf("%2d%2d\n",s[i].data,s[i].parent);
return 0;
}
//测试数据
/*
10
1 2 3 4 5 6 7 8 9 10
1 2
2 4
4 7
3 5
5 8
6 9
9 10
2 5
0 0
*/
//正确输出
/*
1-7
2 0
3 0
4 0
5 2
6-3
7 0
8 2
9 5
10 5
*/
并查集
最新推荐文章于 2024-08-19 22:30:22 发布