在有些问题中我们需要维护若干个集合,并且基于这些集合要频繁的进行以下操作:
并查集(union find)
查询操作:查找一个元素x属于哪一个集合,一般会在每一个集合中选一个元素作为代表,查询的是这个集合中的代表元素
合并操作:将元素x所在的集合与元素y所在的元素合并成一个集合。(注意:合并的是这个集合中的所有元素,不是这两个元素)
判断操作:判断元素x和y是否在同一个集合
这些问题也可以用哈希表来解决 但是效率不高
const int N = 1e6 + 10;
int n;
int fa[N];
//初始化
void init()
{
//让其自己指向自己
for(int i = 1; i <= n; i++)
{
fa[i] = i;
}
}
//查询操作 一直向上找爸爸 也就是找根节点
int find(int x)
{
//用简单的递归就能实现
if(fa[x] == x) //说明就是根节点
return x;
return find(fa[x]);
}
//合并 操作
void un(int x,int y)
{
//找x 和 y 的根节点是谁
int fx = find(x);
int fy = find(y);
//fx表示你所对应的根节点的编号,让其所对应的根节点的编号直接 等于fy
fa[fx] = fy;
}
//判断元素x和y是否在同一集合
bool issame(int x,int y)
{
return find(x) == find(y);
}
int main()
{
return 0;
}
//优化操作 路径压缩
int find(int x)
{
if(fa[x] == x)
return x;
return fa[x] = find(fa[x]);
}