在学并查集之前,我们必须要知道它是干什么用的,在平常图论中,我们往往会使用,但其实它的用法不止于此...
并查集的用处:
1.判断两个元素是否在同一集合
2.合并两个集合
在平常暴力做法做,我们要合并两个集合就是将一个集合中元素添加到另一个中去,但这样往往会超时,那么并查集便诞生了!
并查集是通过一个公共祖先节点判断是否是同一个集合,用数组模拟,数组下标就是对应元素,数组值就是其父节点下标,如果这个节点父节点等于自己,那么这个节点就是根节点。
例:a[3]=2;表示元素3的父节点是2,也说明3和2在同一个集合中。
那么最开始是不是每个元素自己为单独的一个集合,所以父节点为自己(a[i]=i)
for(int i=1;i<=n;i++) a[i]=i;
在合并过程中,我们要先找祖先节点,若两个元素祖先不一样,就合并,就是将一个祖先节点变成另一个的子节点,但是若我们每次都要找祖先节点都要经过中间的父节点很费时间,我们可以让同一个集合元素指向一个节点
先定义查找祖先的函数(因为后面还要用到,就单独写一个函数)
int find(int x){
if(x!=a[x]) return a[x]=find(a[x]);
return x;
}
合并
void unite(int x,int y){
int t1=find(x),t2=find(y);
if(t1!=t2) a[t1]=t2;
}
判断两个节点是否在同一集合只需要看祖先节点是否相同即可
if(find(x)!=find(y))
cout<<"No"<<"\n";
else cout<<"Yes"<<"\n";
谢谢观看——