并查集入门
简介
并查集(Disjoint Set)是多个树状结构的集,一个数组内一般有多个树,每个树都是不相交的,它可处理一些不相交的问题。
举例,假设A同学和B同学是朋友,C同学和D同学也是朋友,现在B同学和C同学也是朋友啦,那么通过B同学和C同学的介绍,A、B、C、D四位同学都是朋友了。现在A、B、C、D就是一个集合啦,而并查集的作用就是将A、B与C、D两个集合的合并。
原理
定义一个数组:
int s[N] //存放集
开始时,每个元素都是一个独立的集,则分别初始化成i,如下图所示:
首先,(1,2)是朋友,合并后如下图所示:
接着,(2,3)是朋友,合并后如下图所示:
现在它就是以单线程的树了。
结构
并查集的初始化
void init_set(int n){ for(int i=0;i<=n;i++) s[i]=i; }
并查集的查找
int find_set(int x){ int r=x; while(r!=s[r]) r=s[r]; int t=x; while(x!=s[x]){ t=x; x=s[x]; s[t]=s[r]; } return r; }
并查集的合并
void union_set(int x,int y){ x=find_set(x); y=find_set(y); if(x!=y) s[x]=s[y]; }
模板
#include<iostream>
#define N 50005
using namespace std;
int s[N];
void init_set(int n){
for(int i=0;i<=n;i++)
s[i]=i;
}
int find_set(int x){
int r=x;
while(r!=s[r])
r=s[r];
int t=x;
while(x!=s[x]){
t=x;