目录
(一)并查集的框架
(1)初始化并查集
const int N=1e5+10;
int p[N];
int Size[N];
int d[N];//x->其祖宗节点的距离不用初始化:全局变量默认为 0
void init()
{
for(int i=1;i<=N;i++)
{
p[i]=i;//每个节点的初始祖宗节点就是自己
Size[i]=1;//每个节点的初始子长度为1(即自己)
}
}
(2)find函数实现路径压缩
int find_without_weight(int x)
{
if(x!=p[x]) p[x]=find_without_weight(p[x]);
return p[x];
}
int find_with_weight(int x)
{
if(p[x]!=x)
{
int root=find_with_weight(p[x]);//找根
d[x]+=d[p[x]];//d[x]到根节点的距离=x->父节点的距离+父节点到根节点的距离
p[x]=root;//记录x的根
}
return p[x];
}
(3)并查集的应用过程
(1)根据题目所求,将所给的点进行拼接,即:
void test_without_weight()//不带权重
{
int n;
cin>>n;//执行n次 合并操作
while(n--)
{
int a,b;//要操作的两个节点
cin>>a>>b;
int pa=find_without_weight(a);//寻找它们的各自的祖宗
int pb=find_without_weight(b);
p[pa]=pb;//将a节点的祖宗节点 连接到b的祖宗节点
}
}
void test_with_weight()//带权重
{
int n;
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
int pa=find_with_weight(a);
int pb=find_with_weight(b);
d[pa]=Size[pb];//pa->pb的距离为 Size[pb]
Size[pb]+=Size[pa];//合并:pb为根的 战舰列边长
p[pa]=pb;
}
}
(2)查询过程:
void query()
{
int a,b;
cin>>a>>b;
int pa=find_without_weight(a);
int pb=find_without_weight(b);
if(pa!=pb) puts("Write what you want here");
else puts("Write what you want here");
}
完整过程:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+10;
int p[N];
int Size[N];
int d[N];//x->其祖宗节点的距离不用初始化:全局变量默认为 0
void init()
{
for(int i=1;i<=N;i++)
{
p[i]=i;//每个节点的初始祖宗节点就是自己
Size[i]=1;//每个节点的初始子长度为1(即自己)
}
}
int find_without_weight(int x)
{
if(x!=p[x]) p[x]=find_without_weight(p[x]);
return p[x];
}
int find_with_weight(int x)
{
if(p[x]!=x)
{
int root=find_with_weight(p[x]);//找根
d[x]+=d[p[x]];//d[x]到根节点的距离=x->父节点的距离+父节点到根节点的距离
p[x]=root;//记录x的根
}
return p[x];
}
void test_without_weight()
{
int n;
cin>>n;//执行n次 合并操作
while(n--)
{
int a,