首页 > 其他分享 >并查集

并查集

时间:2024-01-23 17:23:39浏览次数:25  
标签:元素 int 查集 集合 include find define

并查集是一种集合结构,用来处理集合的合并和查询问题。

主要有两个函数:合并和查询

合并函数表示合并两个不同的集合

查询表示当前元素属于那个集合

逻辑结构是单链表的结构,每个节点向上指向一个属于的集合的代表元素,这个集合的代表元素的next指向它自己成环,表示这个集合的代表元素就是这个有环的节点

牛客测试链接

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 1000001//最大集合个数 

int n;//集合的个数 
int m;//操作的次数 
int f[N];//f[i]表示元素i的下一个元素是谁,如果f[i]等于i那么f[i]就是整个集合的代表元素 
int b[3];//读入输入的数

//查询元素x在那个集合里面 
int find(int x) {
	if (x != f[x]) {//只要不是集合的代表元素 
		f[x] = find(f[x]);//路径压缩 
	}
	
	return f[x];//返回集合的代表元素,向下传递的过程 
}
 
//判断元素a和b是不是在同一个集合当中 
bool isSameSet(int a, int b) {
	return find(a) == find(b);//判断代表两个集合的代表元素相同不相同就可以了 
}

//合并两个集合 
void unionSet(int a, int b) {
	f[find(a)] = find(b);//直接左边的合并到右边,对应着指向根节点 
}

int main(int argc, char* argv[])
{
	sc("%d %d", &n, &m);
	
	//初始化集合 
	for (int i = 1; i <= n; i++) {
		f[i] = i;
	}
	
	while(m--) {
		sc("%d%d%d", b, b + 1, b + 2);
		
		if (b[0] == 2) {
			unionSet(b[1], b[2]);
		}
		else {
			if (isSameSet(b[1], b[2])) {
				pr("Yes\n");
			}
			else {
				pr("No\n");
			}
		}
	} 
	
	return 0;
}

并查集的时间复杂度很高效,每个操作的时间复杂度近似为O(1),本质是反阿克曼函数即O(a(n)),所以近似为O(1)。

标签:元素,int,查集,集合,include,find,define
From: https://www.cnblogs.com/lwj1239/p/17980684

相关文章

  • CF-292-D-并查集
    292-D题目大意给定一张无向图,由\(n\)个顶点\(m\)条边。有\(q\)次询问,每次询问将\([l,r]\)的边删去,问图中有多少连通分量。Solution涉及连通分量,尝试应用并查集解决。记录一个前缀并查集\(pre[i]\),表示前\(i\)条边连通后的图;和一个后缀并查集\(suf[i]\),表示后\(m-i\)条边连通......
  • CF-915-F-并查集
    915-F题目大意给定一棵\(n\)个节点的树,节点带权,设函数\(I(x,y)\)等于点\(x\)到点\(y\)的路径上最大的点权与最小的点权之差。求:\[\sum_{i=1}^{n}\sum_{j=i}^{n}I(i,j)\]Solution令函数\(F(i,j)\)等于点\(x\)到点\(y\)的路径上最大的点权,函数\(G(i,j)\)等于点\(x\)到点\(y\)......
  • 并查集综合
    种类并查集关押罪犯经典种类并查集。考虑要想使最后的结果尽可能小,必须按照怨气值大小将每组关系排序,从大到小依次将罪犯放入监狱。对于放的过程,用并查集维护。由于我们已经将怨气值大小排序,所以对于一组\(a\)与\(b\)的矛盾,将\(a\)与\(b\)不放在同一个监狱一定是最优......
  • 并查集
    并查集基础并查集(\(\sfDisjoint\Set\Union\),\(\sfDSU\))是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素。初始化:初始化时每个节点均为一个集合,因此根节点初始化为自己。for(inti=1;i<=n;i++)fa[i]......
  • abc097d<并查集,排列>
    题目D-Equals给出\(1\simn\)的排列p,给出\(m\)种对换\((p_i,p_j)\),在这\(m\)种对换中任选操作,对原排列对换任意多次。求能够实现的\(p_i=i\)的最大个数为多少?思路将m中对换中能够相互关联的位置归为一组,这组位置之间可通过对换操作实现任意顺序;因而对于一组内的数据,是......
  • 并查集基础 &打击罪犯
    并查集基础真的很基础题目描述:Description某个地区有n(n<=1000)个犯罪团伙,当地警方按照他们的危险程度由高到低给他们编号为1-n,他们有些团伙之间有直接联系,但是任意两个团伙都可以通过直接或间接的方式联系,这样这里就形成了一个庞大的犯罪集团,犯罪集团的危险程度唯一由集团内的......
  • 并查集
    并查集并查集是一种采用树形结构存储的集合,可以高效的查找两个元素是否在一个集合当中以及合并两个集合。这里的树形结构并非仅指二叉树,而是一个节点可以有多个孩子。对于一个并查集的节点,它可以有两个元素,一个存储该节点的数据,另一个用来指向其父节点。当然当我们所存储的元......
  • (来一套)JavaScript并查集模板
    code: classUnionFind{constructor(n){this.parent=Array.from({length:n},(_,i)=>i);this.size=newArray(n).fill(1);this.cnt=n;}findset(x){if(this.parent[x]===x){returnx......
  • 带权并查集
    对于种类并查集主要是考虑清楚到根节点距离分为几类,每一类的意义有的题目相出d数组的含义才能想到用带权并查集//find函数需要变化intfind(intx){if(p[x]!=x){introot=find(p[x]);d[x]+=d[p[x]];p[x]=root;}retur......
  • 并查集基础版
    并查集(byd打到一半没保存直接关了乆乆乆)并查集是一种数据结构,它可以用一个优秀的时间复杂度(路径压缩后接近\(O(1)\))来维持多个集合之间的关系,并进行查找和合并。查找操作我们可以定义一个并查集数组\(p[i]=j\)表示\(i\)的父亲(并查集实际是把一个一个的集合看做树来处理)是\(j......