算法学习系列(十四):并查集

news2024/11/28 22:32:35

目录

  • 引言
  • 一、并查集概念
  • 二、并查集模板
  • 三、例题
    • 1.合并集合
    • 2.连通块中点的数量

引言

这个并查集以代码短小并且精悍的特点,在算法竞赛和面试中特别容易出,对于面试而言,肯定不会让你去写一两百行的代码,一般出的都是那种比较短的,而且还不好想考验思维的那种题,那并查集就将这两点全占了,所以重要性很大,而且竞赛的话也就是将多个知识点合并起来考察,这个也很可能成为一个点,所以话不多说就开始吧。

一、并查集概念

  • 并查集主要有两个作用:
    1.查询两个元素是否在同一集合中,时间复杂度近乎O(1)
    2.将两个集合合并

  • 初始化思路:首先有多个元素,它们最初每个集合只有它们自己,有个p[N]数组,p[i]代表 i 号结点的父结点的下标,p [i] = i

  • 合并思路:先查询它们各自的父结点a,b,然后让p [a] = b 意为a的父亲为b这样a所在的集合就与b所在的集合合并了,如下图所示
    在这里插入图片描述

  • 查询思路:查询自己的父结点是不是根结点,如果是返回,不是则继续递归再次查找父结点的父结点,最后返回根结点,这个是通过递归实现的,这里有个路径压缩的过程,就是最后一个是根结点就会返回,那么就把根结点赋给倒数第三层、第四层…,也就是让每一个结点都指向根结点,类似就是下图所示
    在这里插入图片描述

二、并查集模板

void init()
{
    for(int i = 1; i <= n; ++i) p[i] = i;
}

int find(int x)  //查询编号为x的父结点
{
    if(p[x] != x) p[x] = find(p[x]);  //说明不是父结点,让当前结点指向父结点的父结点,也就是最终的根结点
    return p[x];  //返回父结点
}

三、例题

1.合并集合

一共有 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≤105

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

输出样例:
Yes
No
Yes
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 1e5+10;

int p[N];  //p[i]代表i的父节点的编号
int n, m;  //n个结点,m次询问

void init()
{
    for(int i = 1; i <= n; ++i) p[i] = i;
}

int find(int x)  //查询编号为x的父结点
{
    if(p[x] != x) p[x] = find(p[x]);  //说明不是父结点,让当前结点指向父结点的父结点,也就是最终的根结点 ,注意这里不能写成find(p[x])不然条件就一直没有变化
    return p[x];  //返回父结点
}

int main()
{
    scanf("%d%d", &n, &m);
    
    init();
    
    while(m--)
    {
        char op[2];
        int a, b;
        scanf("%s%d%d", op, &a, &b);

        if(!strcmp(op, "M"))
        {
            a = find(a), b = find(b);  //找到a和b的根结点
            p[a] = b;  //让a指向b,意为a的父亲为b,那么a下的所有结点的父亲都是b
        }
        else
        {
            if(find(a) == find(b)) printf("Yes\n");  //如果两个结点的根结点相同,则在同一个集合
            else printf("No\n");
        }
    }
    
    return 0;
}

所有的用例都通过了
在这里插入图片描述
在这里插入图片描述

2.连通块中点的数量

给定一个包含 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≤105

输入样例:
5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5

输出样例:
Yes
2
3
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 1e5+10;

int p[N], cnt[N];  //来判断根结点所对应的集合的数量,只有根结点有意义
int n, m;

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

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) p[i] = i;
    for(int i = 1; i <= n; ++i) cnt[i] = 1;
    
    while(m--)
    {
        char op[5];
        int a, b;
        scanf("%s", op);
        
        if(!strcmp(op,"C"))
        {
            scanf("%d%d", &a, &b);
            a = find(a), b = find(b);
            if(a == b) continue;
            p[a] = b;
            cnt[b] += cnt[a];
        }
        else if(!strcmp(op,"Q1"))
        {
            scanf("%d%d", &a, &b);
            if(find(a) == find(b)) printf("Yes\n");
            else printf("No\n");
        }
        else
        {
            scanf("%d", &a);
            printf("%d\n", cnt[find(a)]);
        }
    }
    
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1341317.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

table表格中使用el-popover 无效问题解决

实例只针对单个的按钮管用在表格里每一列都有el-popover相当于是v-for遍历了 所以我们在触发按钮的时候并不是单个的触发某一个 主要执行 代码 <el-popover placement"left" :ref"popover-${scope.$index}"> 动态绑定了ref 关闭弹窗 执行deltask…

基于Wenet长音频分割降噪识别

Wenet是一个流行的语音处理工具&#xff0c;它专注于长音频的处理&#xff0c;具备分割、降噪和识别功能。它的长音频分割降噪识别功能允许对长时间录制的音频进行分段处理&#xff0c;首先对音频进行分割&#xff0c;将其分解成更小的段落或语音片段。接着进行降噪处理&#x…

开源轻量级分布式文件系统FastDFS本地部署并实现远程访问服务器

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

【力扣题解】P94-二叉树的中序遍历-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P94-二叉树的中序遍历-Java题解&#x1f30f;题目描述&#x1f4a1;题解&#x1f30f…

微软发布安卓版Copilot,可免费使用GPT-4、DALL-E 3

12月27日&#xff0c;微软的Copilot助手&#xff0c;可在谷歌应用商店下载。目前&#xff0c;只有安卓版&#xff0c;ios还无法使用。 Copilot是一款类ChatGPT助手支持中文&#xff0c;可生成文本/代码/图片、分析图片、总结内容等&#xff0c;二者的功能几乎没太大差别。 值…

华为鸿蒙应用--登录页:网络请求、自定义Loading、MD5密码加密、emitter订阅状态变化、持久化登录状态、隐藏软键盘-ArkTs

HarmonyOS系列 华为鸿蒙应用--底部导航栏Tabs&#xff08;自适应手机和平板&#xff09;-ArkTs_华为鸿蒙应用 csdn 底部导航栏-CSDN博客 华为鸿蒙应用--欢迎页SplashPage倒计时跳过&#xff08;自适应手机和平板&#xff09;-ArkTs_app.media.ic_splash_page_background-CSDN…

云手机引领社交平台运营新潮流

在网络高度发展的今天&#xff0c;社交平台已经成为企业宣传推广的关键渠道之一。传统的社交运营方式已经无法满足效率的要求&#xff0c;云手机因而开始引领社交平台运营的新潮流。本文将深入探讨云手机如何重新定义社交平台运营&#xff0c;为用户和企业带来更为便捷、智能的…

GoLang学习之路,对Elasticsearch的使用,一文足以(包括泛型使用思想)(二)

书写上回&#xff0c;上回讲到&#xff0c;Elasticsearch的使用前提即&#xff1a;语法&#xff0c;表结构&#xff0c;使用类型结构等。要学这个必须要看前面这个&#xff1a;GoLang学习之路&#xff0c;对Elasticsearch的使用&#xff0c;一文足以&#xff08;包括泛型使用思…

腾讯云服务器和轻量服务器选哪个好(各自的优势区别)

腾讯云轻量服务器和云服务器CVM该怎么选&#xff1f;不差钱选云服务器CVM&#xff0c;追求性价比选择轻量应用服务器&#xff0c;轻量真优惠呀&#xff0c;活动 https://curl.qcloud.com/oRMoSucP 轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三…

2023.12.27 关于 Redis 数据类型 List 常用命令

目录 List 类型基本概念 List 类型特点 List 操作命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP RPOP LINDEX LINSERT LREM LTRIM LSET 阻塞版本的命令 阻塞版本 和 非阻塞版本的区别 BLPOP & BRPOP List 类型基本概念 Redis 中的列表&#xff08;list&am…

适用于各种危险区域的火焰识别摄像机,实时监测、火灾预防、安全监控,为安全保驾护航

火灾是一种极具破坏力的灾难&#xff0c;对人们的生命和财产造成了严重的威胁。为了更好地预防和防范火灾&#xff0c;火焰识别摄像机作为一种先进的监控设备&#xff0c;正逐渐受到人们的重视和应用。本文将介绍火焰识别摄像机在安全监控和火灾预防方面的全面应用方案。 一、火…

django之drf框架(排序、过滤、分页、异常处理)

排序 排序的快速使用 1.必须是继承GenericAPIView及其子类才能是用排序 导入OrderingFilter类&#xff0c;from rest_framework.filters import OrderingFilter 2.在类中配置类属性 filter_backends[OrderingFilter] 3.类中写属性 ordering_fields [price,id] # 必须是表的…

华为云CCE-集群内访问-根据ip访问同个pod

华为云CCE-集群内访问-根据ip访问同个pod 问题描述&#xff1a;架构如下&#xff1a;解决方法&#xff1a; 问题描述&#xff1a; 使用service集群内访问时&#xff0c;由于启用了两个pod&#xff0c;导致请求轮询在两个pod之间&#xff0c;无法返回正确的结果。 架构如下&am…

Appium+python自动化(七)- 初识琵琶女Appium(千呼万唤始出来,犹抱琵琶半遮面)- 上(超详解)

简介 “千呼万唤始出来&#xff0c;犹抱琵琶半遮面”&#xff0c;经过前边的各项准备工作&#xff0c;终于才把appium这位琵琶女请出来。那么下边就由宏哥给各位看官、小伙伴们和童鞋们来引荐这位美女&#xff08;帅哥&#xff09;。这一篇主要是对前边的内容做一个小小的总结&…

功能测试知识超详细总结

一、测试项目启动与研读需求文档 &#xff08;一&#xff09; 组建测试团队 1、测试团队中的角色 2、测试团队的基本责任 尽早地发现软件程序、系统或产品中所有的问题。督促和协助开发人员尽快地解决程序中的缺陷。帮助项目管理人员制定合理的开发和测试计划。对缺陷进行跟…

远程桌面的3389端口如何修改

远程桌面是windows的一个功能组件&#xff0c;通过这个组件可以远程控制某台电脑的电脑桌面&#xff0c;使用过windows远程桌面的人都清楚&#xff0c;大家都知道3389是远程桌面的默认端口号&#xff0c;如果将这个端口在路由器中映射出去&#xff0c;将极大的增加服务器的风险…

.NET Core NPOI导出复杂Excel

一、引入NPOI NuGet&#xff1a; NPOI GitHub源码地址&#xff1a; GitHub - tonyqus/npoi: a .NET library that can read/write Office formats without Microsoft Office installed. No COM, no interop. 版本说明&#xff1a; NPOI 2.4.1 &#xff08;注意不同版本可能使用…

elasticsearch-hadoop.jar 6.8版本编译异常

## 背景 重新编译 elasticsearch-hadoop 包&#xff1b; GitHub - elastic/elasticsearch-hadoop at 6.8 编译 7.17 版本时很正常&#xff0c;注意设置下环境变量就好&#xff0c;JAVA8_HOME/.... 编译 6.8 版本时&#xff08;要求jdk8 / jdk9&#xff09;&#xff0c;出现…

经典目标检测YOLO系列(一)YOLOV1的复现(1)总体架构

经典目标检测YOLO系列(一)实现YOLOV1网络(1)总体架构 实现原版的YOLOv1并没有多大的意义&#xff0c;因此&#xff0c;根据《YOLO目标检测》(ISBN:9787115627094)一书&#xff0c;在不脱离YOLOv1的大部分核心理念的前提下&#xff0c;重构一款较新的YOLOv1检测器&#xff0c;来…

毕业/课程设计——基于STM32的智能灯光控制系统(物联网、智能家居、手机APP控制、语音控制)

文章首先介绍本系统所包含的功能&#xff0c;主要包含六方面功能&#xff0c;之后逐步分享开发过程&#xff0c;其流程如下&#xff1a;点亮灯带&#xff08;三极管&#xff09;→调节灯光亮度&#xff08;PWM&#xff09;→为系统添加远程控制功能→为系统添加语音识别功能→添…