并查集
2016-05-23 17:05
344 查看
什么是并查集,并查集就是先给出一些关系,然后你就可以把这些关系合并成一个集合,然后在询问你里面的某些元素之间是不是有关系
并查集的英文叫Union--Find(其实是该算法包含union和find两个函数)
代码:
并查集的英文叫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;
}
相关文章推荐
- 编译ROS工作空间某一个包的命令
- 9. Spark Streaming技术内幕 : Receiver在Driver的精妙实现全生命周期彻底研究和思考
- C++作业6
- java基础四---jdk内置工具的使用
- c#之习题
- views/admin/main.hbs: Cannot read property 'hash' of undefined
- $(document).ready()即$()方法和window.onload方法的比较
- Spring bean的初始化及销毁
- iOS tableview 选中一行后,不显示选中颜色
- 暴力英语学习法 + 严格的目标管理 = 成功快速靠谱的学好英语
- 李龙刚的情人节表白PHP程序源码下载
- Angular服务Request异步请求的详细分析
- terminal 的一些指令
- getopt、getopt_long、getopt_long_only
- listView 异步加载图片
- (十六)洞悉linux下的Netfilter&iptables:开发自己的hook函数【实战】(下)
- SQL server 多表查询与视图的使用
- PHP的反射机制
- 03.LoT.UI 前后台通用框架分解系列之——多样的表格
- C++多态的实现及原理详细解析