有关并查集的重要操作
作者:
弥海砂
,
2024-07-18 17:04:35
,
所有人可见
,
阅读 2
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
int p[N],cnt[N];
//路径压缩优化并查集
int find(int x)//返回x所在集合的编号(即返回根节点)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
p[i]=i; //初始化(将每个点看作自己的一个集合)
cnt[i]=1; //表示每一个集合中点的数量
}
while(m--)
{
int a,b; cin>>a>>b;
//当a和b不连通时才需要连接
if(find(a)==find(b)) continue;
//将a和b所在的两个集合的点的数量相加
cnt[find(a)]+=cnt[find(b)];
//合并集合(连通a,b两个集合)
p[find(a)]=find(b);
//询问两个元素是否在同一个集合当中
if(find(a)==find(b)) puts("Yes");
else puts("No");
cin>>a;
cout<<size[find(b)]<<endl; //统计a元素所在连通块中点的数量
}
int res=0;
for(int i=1;i<=n;i++)
if(p[i]==i) res++; //统计连通块的数量
//将所有集合连通需要增加的边数=连通块的数量-1
cout<<res-1<<endl;
return 0;
}