并查集的基本操作和用法(代码片段)

JunMain JunMain     2023-01-09     665

关键词:

并查集

并查集的作用:

1.合并区间

2.判断两个数是否再同一个集合之中

3.寻找联通子图的的个数

并查集的关键函数find(x)与p[]数组 寻找x的祖宗节点

/*
	find函数用于寻找祖宗节点
*/

int find(int x)

    if (p[x] != x)	find(p[x])
    return p[x];



/*
	p[N]	存储每个节点的祖宗节点
	初始化p[N]		一开始每个节点的祖宗是他自己, 一个数作为一个集合
*/
for (int i = 1; i <= n; i ++)	p[i] = i;

/*	
	合并集合	(a,b)所在的集合
*/
if (find(a) != find(b))			//当不是一个集合才进行合并
    p[find(a)] = find(b);		//让a的祖宗节点 归顺b的祖宗节点

/*
	cnt[N]数组存储每个集合元素个数
*/
for (int i = 1; i <= n; i ++)	cnt[i] = 1;		//初始化一开始每个集合只有一个元素
if (find(a) != find(b))					//集合元素变化只会再合并的时候变换

    a = find(a), b = find(b);
    p[a] = b;
    cnt[b] += cnt[a];				//b集合中的元素个数要加上a中元素个数



合并集合

题目描述

一共有 n 个数,编号是 1∼n,最开始每个数各自在一个集合中。

现在要进行 m 个操作,操作共有两种:

M a b,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;
Q a b,询问编号为 a 和 b 的两个数是否在同一个集合中;

输入格式

第一行输入整数 n 和 m。

接下来 m 行,每行包含一个操作指令,指令为 M a b 或 Q a b 中的一种。

输出格式

对于每个询问指令 Q a b,都要输出一个结果,如果 a 和 b 在同一集合内,则输出 Yes,否则输出 No。

每个结果占一行。

数据范围

1 ≤ n , m ≤ 1 0 5 1≤n,m≤10^5 1n,m105

样例

输入样例:
4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4
输出样例:
Yes
No
Yes

代码

#include <bits/stdc++.h>
using namespace std;

int f[100010];

int find(int x)  // 寻找该点的祖宗节点

    if (f[x] != x) f[x] = find(f[x]);
    return f[x];


int main()

    int n, m;
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++)   f[i] = i;			//初始化
    
    while (m -- )
    
        int a, b;
        char ch[2];
        scanf("%s%d%d", ch, &a, &b);
        if (*ch == 'M')  f[find(a)] = find(b);		//把a的祖宗节点,改成b的祖宗节点,集合合并
        else 
        
            if (find(a) == find(b))     printf("Yes\\n");
            else printf("No\\n");
        
    
    
    
    return 0;


连通块中点的数量

题目描述

给定一个包含 n 个点(编号为 1∼n)的无向图,初始时图中没有边。

现在要进行 m 个操作,操作共有三种:

C a b,在点 a 和点 b 之间连一条边,a 和 b 可能相等;
Q1 a b,询问点 a 和点 b 是否在同一个连通块中,a 和 b 可能相等;
Q2 a,询问点 a 所在连通块中点的数量;

输入格式

第一行输入整数 n 和 m。

接下来 m 行,每行包含一个操作指令,指令为 C a b,Q1 a b 或 Q2 a 中的一种。

输出格式

对于每个询问指令 Q1 a b,如果 a 和 b 在同一个连通块中,则输出 Yes,否则输出 No。

对于每个询问指令 Q2 a,输出一个整数表示点 a 所在连通块中点的数量

每个结果占一行。

数据范围

1 ≤ n , m ≤ 1 0 5 1≤n,m≤10^5 1n,m105

样例

输入样例:
5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5
输出样例:
Yes
2
3

题解

多了一个cnt[N]数组记录每个祖宗节点所包含的节点数量(包括自己), 初始化是1

cnt[N]的变化只发生在两个集合合并的时候, 合并后的祖宗节点cnt加上原来集合cnt的个数

并且多了一层判断 a = find(a), b = find(b) 当a != b 的时候才合并, 一为了防止之前已经合并过的集合再次合并

二为了防止一开始 a == b 的情况

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;

int f[N], cnt[N];

int find(int x)

    if (f[x] != x)  f[x] = find(f[x]);
    return f[x];



int main()

    int n, m, a, b;
    string op;
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++ )  f[i] = i, cnt[i] = 1;
    
    while (m -- )
    
        cin >> op;
        if (op == "C")
        
            scanf("%d%d", &a, &b);
            a = find(a), b = find(b);
            if (a != b)
            
                f[a] = b;
                cnt[b] += cnt[a];
            
            
        
        else if (op == "Q1")
        
            scanf("%d%d", &a, &b);
            if (find(a) == find(b))     printf("Yes\\n");
            else printf("No\\n");
        
        else 
        
            scanf("%d", &a);
            a = find(a);
            printf("%d\\n", cnt[a]);
        
    
    
    
    return 0;

数据结构--并查集的原理及实现(代码片段)

... 并查集(Union/Find)从名字可以看出,主要涉及两种基本操作:合并和查找。这说明,初始时并查集中的元素是不相交的,经过一系列的基本操作(Union),最终合并成一个大的集合。而在某次合并之后,有一种合理的需求:某两... 查看详情

数据结构——并查集的详细解析和实现(代码片段)

...帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦一.并查集的定义1.并查集是一种树型的数据结构,用于处理一些不相交集合(disjointsets)的合并及查询问题。2.并查集通常包含两种操作查 查看详情

数据结构——并查集的详细解析和实现(代码片段)

...帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦一.并查集的定义1.并查集是一种树型的数据结构,用于处理一些不相交集合(disjointsets)的合并及查询问题。2.并查集通常包含两种操作查 查看详情

并查集的删除操作(代码片段)

...一开始所有信件都是单独的文件夹。其实就是一个简单的并查集删除的操作,当删除时就创建新的结点来代替它,要注意的是数组的范围,虽然信件只有10的5次方,但是操作有10的6次方,因为删除时还得 查看详情

关于并查集的一切全在这里了(代码片段)

文章目录并查集初识「并查集」常用术语「并查集」基本思想「并查集」的两个实现方式QuickFind方式实现并查集QuickFind工作原理:代码实现与验证时间复杂度QuickUnion方式实现并查集QuickUnion的工作原理为什么QuickUnion比QuickFind... 查看详情

并查集的学习和模拟实现(代码片段)

并查集将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这... 查看详情

并查集详解(代码片段)

目录并查集(Union-Find)初始化的两种方法:并集的三种方法:查集的两种方法:“并“、”查”的基本方法与优化源代码并查集(Union-Find)常用来解决动态连通性问题。曾有外国网友在StackExchange上发起过投票,选出世界十大有... 查看详情

并查集(入门)(代码片段)

首先先看一道很简单的并查集的题目:https://vjudge.net/contest/297398#problem/A这道题就是让你判断两两城镇之间是否联通  如果不联通就要修建一条道路 就我的理解来说,如果单独使用并查集就是为了合并有相同根结点(或者理... 查看详情

并查集(代码片段)

主要内容本文主要记录并查集的基本实现方法,并逐步将一些例题填充到文章中。并查集能做什么并查集可以:1.合并集合2.查找两个元素是否在同一个集合内3.集合数量4.确定元素属于哪个集合。完整代码示例classUFpublic:UF();UF(int... 查看详情

树的应用——并查集及实现代码(代码片段)

文章目录什么是并查集亲戚问题并查集的实现改进——路径压缩进一步改进——合并并查集的用途什么是并查集 并查集是一种树型的数据结构,用于处理一些不相交集合(disjointsets)的合并及查询问题。常常在使用... 查看详情

并查集的基本运用poj1611

用并查集的情况是在比如A和B联通 B和C联通那么ABC联通这类情况下算某个元素所在集合的元素个数。.并查集数据结构用数组就行,数组的下标表示相应的一个主体,对应的值表示它的父节点的索引,指向父节点。根节点的值... 查看详情

并查集的原理及实现(代码片段)

一、定义  并查集是一种树型的数据结构,用于处理一些不相交集合(DisjointSets)的合并及查询问题。二、代码实现  在并查集结构中,用一个pre[]数组来存储当前结点的父亲结点,有两个函数,found()函数用来寻找根结点,... 查看详情

poj2236(并查集的应用)(代码片段)

WirelessNetworkTimeLimit: 10000MS MemoryLimit: 65536KTotalSubmissions: 35832 Accepted: 14863DescriptionAnearthquaketakesplaceinSoutheastAsia.TheACM(AsiaCooperatedMedicalt 查看详情

数据结构一篇文章学懂并查集+lrucache,拿来吧你!(代码片段)

并查集--LRUCache并查集的概念一、并查集的用途并查集的结构解释并查集的实现并查集相关习题习题1.leetcode朋友圈习题2.leetcode等式方程的可满足性并查集的思考与提升二、LRUCache的介绍1.什么是LRUCache习题.LRU缓存机制总结好文建... 查看详情

并查集的小节(代码片段)

寒假就看了并查集的视频,可是一直没怎么用了,现在终于还是拾起,看了这方面的视频还是很好理解的;看了挑战程序竞赛这本后,感觉大佬的思路就是简单,高效,可以首先写几个函数,分部实现各个功能,按照思路:1,... 查看详情

数据结构-树并查集的定义及其操作(代码片段)

...化3查找操作4并操作1数据结构定义#defineMAX50intUFSets[MAX];//并查集2初始化//参数:并查集SvoidInit(intS[])inti;for(i=0;i<MAX;i++)S[i]=-1;【注】根结点可用来保存该子集合的元素个数(负数表示)。3查找操作寻找包... 查看详情

nowcoder106c.professionalmanager(统计并查集的个数)(代码片段)

题意:给出四种操作:1.合并u,v两棵树2.从u所在的集合中删除u3.询问u所在集合有多少颗树4.询问u,v是否在同一个集合分析:对于删除操作,只要新开一个点代替原来的点即可。#include<bits/stdc++.h>usingnamespacestd;constintmaxn=2e5+5e... 查看详情

并查集的实现(代码片段)

1intpar[MAX_N];//每个节点的父节点2intrank[MAX_N];//树的高度3//初始化n个元素4voidinit(intn)5for(inti=0;i<n;i++)6par[i]=i;//初始时每个节点自成一树7rank[i]=0;891011//查询树的根12intfind(intx)13if(par[x]=x)14returnx;1516else17r 查看详情