并查集

题单

这个专辑之前写在洛谷上,但年久失修,所以我决定在博客上重写一遍

正文

定义

并查集,顾名思义,是关于合并以及查询的集合,实现为一个森林,每一棵树是一个集合。支持两种操作,合并以及查询,合并是指将两个元素所在的两个树合并,查询则是查找一个元素所在树的根结点。

初始化

在没有任何操作进行的时候,所有元素所在树的根结点都是自己

for(int i=1;i<=n;i++)
{
  fa[i]=i;
}

查询

对于每个要查询的结点,向上寻找 \(fa[x]\),直到某一层上 \(fa[x]=x\) 为止。答案就是当时的 \(x\)。这部分通常用递归的方式完成

int find(int x)
{
	if(fa[x]==x) return x;
	return find(fa[x]);
}

合并

路径压缩

由于我们只关心每颗树根结点的信息,所以直接让一棵树中的所有点全部连接到根结点上,即为路径压缩。
这一步类似于记忆化搜索,只需要在查询时让 \(fa[x]\) 指向根节点即可。

int find(int x)
{
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
} 

合并操作

同理,由于我们只关心每颗树根结点的信息,直接让 \(A\) 子树的根结点连到 \(B\) 子树的根结点即可。

void merge(int x,int y)
{
	int fx=find(x),fy=find(y);
	fa[fx]=fy;
}

Luogu P3367

并查集模板题仅需上述两种操作即可通过

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int fa[N];
int find(int x)
{
	if(x==fa[x])
	{
		return x;
	}
	return fa[x]=find(fa[x]);
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
	}
	while(m--)
	{
		int op,x,y;
		cin>>op>>x>>y;
		if(op==1)
		{
			fa[find(x)]=find(y);
		}
		else
		{
			int fx=find(x),fy=find(y);
			if(fx==fy)
			{
				cout<<"Y"<<endl;
			}
			else
			{
				cout<<"N"<<endl;
			}
		}
	}
	return 0;
}

Luogu P1111

简述题意

\(n\) 个点,\(m\) 条未连接的边,每条边在第 \(t_i\) 时间可以通车,求最少需要多少时间能使任意两点通车

解法

因为我们要求最小时间,可以把边按时间排序,并循环 \(n\) 次,每次对并查集进行一次合并操作,直到所有点都在一个集合为止。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int fa[N],sz[N];
int find(int x)
{
	if(x==fa[x])
	{
		return x;
	}
	return fa[x]=find(fa[x]);
}
struct node
{
	int u,v,w;
	void read()
	{
		cin>>u>>v>>w;
	}
}g[N];
bool cmp(node n1,node n2)
{
	return n1.w<n2.w;
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
		sz[i]=1;
	}
	for(int i=1;i<=m;i++)
	{
		g[i].read();
	}
	sort(g+1,g+m+1,cmp);
	for(int i=1;i<=m;i++)
	{
		int u=g[i].u,v=g[i].v,w=g[i].w;
		int fu=find(u),fv=find(v);
		if(fu==fv)
		{
			continue;
		}
		fa[fu]=fv;
		sz[fv]+=sz[fu];//用sz数组统计每个集合的元素数量 
		if(sz[fv]==n)
		{
			cout<<w<<endl;
			return 0;
		}
	}
	cout<<-1<<endl; 
	return 0;
}

Luogu P1197

posted @ 2026-10-06 20:13  jianghaochen  阅读(3)  评论(0)    收藏  举报