您的位置:首页 > 其它

并查集

2016-05-23 17:05 344 查看
什么是并查集,并查集就是先给出一些关系,然后你就可以把这些关系合并成一个集合,然后在询问你里面的某些元素之间是不是有关系

并查集的英文叫Union--Find(其实是该算法包含union和find两个函数)

代码:

/*******并查集**************

*************************/

#include<stdio.h>

#include<stdlib.h>

int find(int *number,int p)

{

//寻找节点p的组号--根节点

while(p!=number[p])

{

//路径压缩,让该节点存放它的爷爷节点

number[p]=number[number[p]];

p=number[p];

}

return p;

}

void find_union(int *number,int *sz,int a,int b)

{

//将关系a,b合并为一个集合

int i,j;

i=find(number,a);

j=find(number,b);

if(i==j) return ;

//小的树合并到大的树那里,可以减少find里的while操作次数

if(sz[i]>sz[j])

{

number[j]=i;

sz[i]=sz[i]+sz[j];

}

else

{

number[i]=j;

sz[j]=sz[j]+sz[i];

}


}


int main(void)

{

int n,m,t,a,b;

scanf("%d",&n);

int *number,i;

//存储关系的数组

number=(int *)malloc(sizeof(int)*n);

for(i=0;i<n;i++)

number[i]=i;


//辅助数组,存放每颗树的节点数量

int *sz;

sz=(int *)malloc(sizeof(int)*n);

for(i=0;i<n;i++)

sz[i]=1;


scanf("%d",&m);

for(i=0;i<m;i++)

{

scanf("%d %d",&a,&b);

find_union(number,sz,a,b);

}



//t对询问关系,有关系就y,否则就n

scanf("%d",&t);

for(i=0;i<t;i++)

{

scanf("%d %d",&a,&b);

a=find(number,a);

b=find(number,b);

if(a==b) putchar('y');

    else putchar('n');


putchar('\n');

}



free(number);

free(sz);

return 0;

}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: