并查集:
1. 应用:并查集一般常被应用于处理一些不相交集合的查找和合并问题。最经典的问题:已知某镇上有n个村庄(可以想象成n个不相连的点),其中已有有m条路联通这n个村庄,问至少还需再建多少条路,才能使n个村庄都连起来(村庄与村庄不一定直接连起来,只要保证能从某个村庄到某个村庄即可),又或者问某个村和某个村是否相连。 可以在纸上画一画,便于理解。
2.定义:
英文:Disjoint Set,即“不相交集合”
将编号分别为1…N的N个对象划分为不相交集合,
在每个集合中,选择其中某个元素代表所在集合。
常见两种操作:
合并两个集合
查找某元素属于哪个集合
所以,也称为“并查集”
为什么要先给出应用呢,因为我发现直接给出定义会使对概念理解的不深刻,先给出应用便于结合它理解定义。
3.代码实现:
相信现在你已经对并查集算法有了一个大致的印象,已经迫不及待的想做出这道题了吧,哈哈^~^.
以问的第二个问题为例:
#include <stdio.h>
int bin[100002];
int findx(int x)寻找父节点的函数
{
int r=x;
while(bin[r] !=r)
r=bin[r];
return r;
}
void merge(int x,int y)
{
int fx,fy;
fx = findx(x);
fy = findx(y);
if(fx != fy)
bin[fx] = fy;
}
int main()
{
int n, m, i, j, x[10002], y[10002], k, count=0;//n,m分别为村庄数和已连接的路的条数,x,y为已连接的村庄的编号
//c, d 代表输入的两个村庄的编号,问这两个村庄是否相连
while(scanf("%d",&n)!=EOF)
{
count = 0;
for(i=0;i<n;i++)//使单独的点的父节点为自己
bin[i] = i;
scanf("%d",&m);
for(j=0; j<m; j++)
{
scanf("%d %d",&x[j],&y[j]);//输入m组已知信息
}
scanf("%d %d", &c, &d);
此处 留空 可根据题意自行编写。
printf("%d\n", count);
}
return 0;
}
未完》》》》》