本文已参与[新人创作礼]活动,一起开启掘金创作者之路。
定义: 并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。比如说,我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。
主要构成: 并查集主要由一个整型数组pre[ ]和两个函数find( )、join( )构成。 数组 pre[ ] 记录了每个点的前驱节点是谁,函数 find(x) 用于查找指定节点 x 属于哪个集合,函数 join(x,y) 用于合并两个节点 x 和 y 。
作用: 并查集的主要作用是求连通分支数(如果一个图中所有点都存在可达关系(直接或间接相连),则此图的连通分支数为1;如果此图有两大子图各自全部可达,则此图的连通分支数为2……)
并查集的初始化 将所有元素的前驱都设为他自己。
find()函数 我们需要定义一个数组:int pre[1000]; (数组长度依题意而定)。这个数组记录了每个元素的前驱结点是谁。比如说pre[16]=6就表示16号元素的前驱结点是6号。如果一个元素的前驱结点就是他自己,那说明他就是代表元了,查找到此结束。也有一个元素自及组成一个集合的,那么这个集合的代表元就是自己。
int find(int x) //查找x的代表元 { while(pre[x] != x) //如果x的前驱结点不是自己 x = pre[x]; return x; } 1 2 3 4 5 6 join函数 join函数的作用是将两个集合合并,合并两个集合的关键是找到两个集合的代表元,将其中一个作为另一个的前驱结点即可。
void join(int x,int y)
{
int fx=find(x), fy=find(y);
if(fx != fy)
pre[fx]=fy; //fy做fx的前驱结点
}
1
2
3
4
5
6
千万注意不要直接将读入的两个数据,其中一个作为另一个的前驱结点,而应该是找到两个数据的代表元,将两个代表元合并,也就是将两个集合合并。