-设S1= {0, 6,
7, 8 },S2= { 1, 4, 9 },S3= { 2, 3, 5
}
-为简化讨论,忽略实际的集合名,仅用表示集合的树的根来标识集合。 -为此,采用树的双亲表示作为集合存储表示。集合元素的编号从0到n-1。其中n是最大元素个数。在双亲表示中,第i个数组元素代表包含集合元素i的树结点。根结点的双亲为-1,表示集合中的元素个数。为了区别双亲指针信息(
≥ 0 ),集合元素个数信息用负数表示。
下标parent
集合S1,
S2和S3的双亲表示:
#include
using namespace std;
int up[10000];
int rank[10000];
void makeset(int x)
{
up[x]=-1; //表示x是树根
rank[x]=0;
}
int find(int x)
{
int r=x;
while(up[r]!=-1) /获得根节点r
r=up[r]; //类似链表中的r=next[r]的意思,这里是向根节点移动
while(x!=r) //路径压缩
{
int t=up[x]; //先保存x的父节点
up[x]=r; //把x指向r,也就是说x的父节点变成r
x=t; //x向上移动
}
return r;
}
void join(int a,int b)
{
int root1=find(a);
int root2=find(b);
if(rank[root1]>rank[root2])
{
up[root2]=root1; //root1成为root2的父节点
}
else
up[root1]=root2;
if(rank[root1]==rank[root2])
rank[root2]++;
}
int
main()
{
int
i,a,b,c,d;
while(cin>>N>>M)
{
for(i=1;i<=N;i++)
makeset(i);
for(i=1;i<=M;i++)
{
cin>>a>>b;
if(find(a)!=find(b))
unionone(a,b);
}
cin>>Q;
for(i=1;i<=Q;i++)
{
cin>>c>>d;
if(find(c)==find(d))
cout<
else
cout<
}
}
return
0;
}
接下来一篇树来实现
typedef
struct uf_n_t
{
int
rank;
item_t
*item;
struct
uf_n_t *up;
}uf_node_t;
uf_node_t *insert(item_t
*new_item)
{
uf_node_t
*new_node;
new_node=get_node();
new_node->item=new_item;
new_node->rank=0;
new_node->up=NULL;
return
(new_node);
}
int
same_class(uf_node_t *node1,uf_node_t
*node2)
{
uf_node_t *root1, *root2,
*tmp;
for(root1=node1;root1->up!=NULL;root1=root1->up)
;
for(root1=node2;root2->up!=NULL;root2=root2->up)
;
while()
}