并查集:
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 ", count); } return 0; }
未完》》》》》