【图论】并查集的学习和使用

news2025/3/17 14:37:44

目录

并查集是什么?

举个例子

组成

父亲数组:

find函数:

union函数:

代码实现:

fa[] 初始化code:

find code:

递归实现:

非递归实现:

union code :

画图模拟:

路径压缩:

路径压缩Code:


并查集是什么?

是一种树形的数据结构,一般用来处理集合的合并,查询操作。

举个例子

告诉你1的父节点是2 2的父节点是3 4的父节点是5 6没有父节点 那么可以画出

三个集合,或者说是树 。然后我们一般用并查集判断:①有几棵树 也就是有几个集合 ② 两个点是否同属于一个集合 ③一个点是不是属于这棵树 

组成

主要是通过一个父亲数组和一个find函数、一个union函数实现的。

父亲数组:

记录一个节点的父结点 初始化为自己 也就是一开始自己就是自己的父结点 自己单独属于一个集合

find函数:

根据邻接关系 找到一个结点的根结点 如果两个结点的通过find函数寻找出来的结点相同 则同属一个集合

union函数:

遍历邻接关系时 将两个邻接的结点父亲数组更新的作用 具体来说 判断若两个结点通过find函数寻找出来的根节点不相同 也就是不属于一个集合 则将一个集合并入另一个集合 通过把前一个结点的根节点 的父亲数组 标记为第二个结点的根节点 则两个集合就合并了

代码实现:

fa[] 初始化code:

for(int i=0;i<n;++i)
       fa[i]=i;

find code:

递归实现:

int finds(int a){
    if(a!=fa[a]){
        fa[a]=finds(fa[a]);
    }
    return fa[a];
}

非递归实现:

int finds(int a){
    while(a!=fa[a]){
        a=fa[a];
    }
    return fa[a];
}

详细解释:一个结点 只有父结点是自己 也就是fa[]数组中是自己 才能称为根节点 finds函数就是判断一个结点是否为根结点 如果不是 就继续向上finds他的父节点 看是不是根结点 直到找到根节点 返回 这个根节点可以称之为一个集合的标志

union code :

void unions(int x,int y){
    int fx=finds(x);
    int fy=finds(y);
    if(fx!=fy){
        fa[fx]=fy;
    }
}

详细解释:unions函数是用于遍历邻接关系时 更新集合关系。传入两个结点 找到他们的根节点 也就是他们所属集合的标志 判断是否相同 也就是判断是否从属于一个集合 如果不属于一个集合 则把第一个集合的根节点 的父亲结点 更新为 第二个集合的根节点。也就是把第一个集合和第二个集合合并 并且根节点保留为第二个集合的根节点 。

画图模拟:

①我们要判断两个点是否属于一个集合 只要用find函数即可 

②我们要判断共有几个集合 只要看fa数组中有几个 i=fa[i]即可 因为fa[i]等于i 代表是集合里的根结点 一个集合只有一个根结点 所以根结点数即为集合数量

路径压缩:

可以观察到 每次调用find函数都需要经历一串长长的递归 这正是函数时间花费的地方 考虑优化的地方 我们可以直接把fa[i]数组标记为i结点所属集合的根节点 也就是把整条路径上的fa[i]数组都标记为根节点 按上面画图的例题来说 就是把fa[1] fa[3] fa[4] 全部标记为4 这样调用find函数的时候就特别快,一步到位。要想完成这个操作 只要在find函数后加一步 每次find的时候 找到了根节点的值 保存 再用一个while循环向上查找 把整条路径上的结点的fa[]值都更新为找到的根节点 

路径压缩Code:

int new_finds(int a){
    int aa=a;//保存一下查找的点 也就是路径的底部
    if(a!=fa[a]){
        fa[a]=finds(fa[a]);//找到了根节点
    }
    while(aa!=fa[a]){//向上更新整条路径
        int temp=fa[aa];//先存储路径的下一个点
        fa[aa]=fa[a];//路径压缩一个
        aa=temp;//再压缩下一个点
        
    }
    return fa[a];
}

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

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

相关文章

欢乐力扣:反转链表

文章目录 1、题目描述2、思路 1、题目描述 反转链表。  给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 2、思路 借助cur指针和pre双指针来调整链表的前后指向。 # Definition for singly-linked list. # class ListNode: # def __i…

什么是大带宽服务器

什么是大带宽服务器&#xff1f; 在深入探讨大带宽之前&#xff0c;让我们先明确带宽的概念。带宽与我们日常所说的宽带有所不同&#xff0c;宽带是运营商为满足家庭或商业上网需求所提供的服务&#xff0c;而带宽则特指数据的传输速度&#xff0c;尤其是上行速度。大带宽服务…

【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解

活动发起人小虚竹 想对你说&#xff1a; 这是一个以写作博客为目的的创作活动&#xff0c;旨在鼓励大学生博主们挖掘自己的创作潜能&#xff0c;展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴&#xff0c;那么&#xff0c;快来参加吧&#xff01…

SSM基础专项复习4——Maven项目管理工具(1)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架&#xff08;1&#xff09;-CSDN博客 3、SSM基础专项复习3——Spring框架&#xff08;2&#xff09;-CSDN博客 文章目录 系列文章 1. Maven 的概念 1.1. 什么是 Maven 1.2. 什…

使用c#进行串口通信

一、串口通信协议 1.串口通信协议简介 串口通信&#xff08;serial communication&#xff09;是一种设备间非常常用的串行通信方式&#xff0c;大部分电子设备都支持&#xff0c;电子工程师再调试设备时也经常使用该通信方式输出调试信息。讲到某一种通信协议&#xff0c;离…

Web开发-PHP应用鉴别修复AI算法流量检测PHP.INI通用过滤内置函数

知识点&#xff1a; 1、安全开发-原生PHP-PHP.INI安全 2、安全开发-原生PHP-全局文件&单函数 3、安全开发-原生PHP-流量检测&AI算法 一、演示案例-WEB开发-修复方案-PHP.INI配置 文章参考&#xff1a; https://www.yisu.com/ask/28100386.html https://blog.csdn.net/…

蓝桥模拟+真题讲解

今天谁一篇文章哈 &#xff01; 由于本篇文章有些的题目只有图片&#xff0c;因此还望各位见谅。 目录 第一题 题目解析 代码原理 代码编写 填空技巧---巧用python 第二题 题目解析 ​编辑 填空技巧---巧用python 第三题 题目链接 题目解析 必备知识 解题技巧 …

C语言【数据结构】:时间复杂度和空间复杂度.详解

引言 详细介绍什么是时间复杂度和空间复杂度。 前言&#xff1a;为什么要学习时间复杂度和空间复杂度 算法在编写成可执行程序后&#xff0c;运行时需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏&#xff0c;一般是从时间和空间两个维度来衡量的&#xff0c;即时…

基于Python的selenium入门超详细教程(第2章)--单元测试框架unittest

学习路线 自动化测试介绍及学习路线-CSDN博客 ​自动化测试之Web自动化&#xff08;基于pythonselenium&#xff09;-CSDN博客 基于Python的selenium入门超详细教程(第1章)--WebDriver API篇-CSDN博客 目录 前言&#xff1a; 一、单元测试 1. 单元测试的定义 2. 单元测…

日志、类加载器、XML(配置文件)

目录 一、日志1.日志技术的概述2.日志技术的体系a. Logback 3.日志的级别 二、类加载器1.概述2.类加载时机3.类加载过程3.类加载器的分类4.常用方法 三、XML&#xff08;配置文件&#xff09;1.概述2.XML的基本语法3.XML的文档约束a.DTD约束b.schema约束 4.XML文档解析a.Dom4jb…

AI大白话(一):5分钟了解AI到底是什么?

&#x1f31f;引言&#xff1a; 在这个信息爆炸的时代&#xff0c;“人工智能”、“AI”、“机器学习”、"深度学习"等词汇频繁出现在我们的生活中。 从手机里的语音助手&#xff0c;到网购平台的个性化推荐&#xff0c;再到最近大火的AI绘画和ChatGPT&#xff0c;人…

蓝桥与力扣刷题(蓝桥 字符统计)

题目&#xff1a;给定一个只包含大写字母的字符出 S, 请你输出其中出现次数最多的字符。如果有多个字母均出现了最多次, 按字母表顺序依次输出所有这些字母。 输入格式 一个只包含大写字母的字等串 S. 输出格式 若干个大写字母&#xff0c;代表答案。 样例输入 BABBACAC样…

AtCoder Beginner Contest 397(ABCDE)

目录 A - Thermometer 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; B - Ticket Gate Log 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; C - Variety Split Easy 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; D - Cubes 翻译&#xff1a…

Profinet转Profinet以创新网关模块为核心搭建西门子和欧姆龙PLC稳定通讯架构案例​

你是否有听过PROFINET主站与PROFINET主站之间需要做数据通讯有需求&#xff1f; 例如西门子1500与霍尼韦尔DCS系统两个主站之间的通讯。应用于PROFINET为主站设备还有欧姆龙、基恩士、罗克韦尔、施耐德、GE、ABB等品牌的PLC或DCS、FCS等平台。在生产或智能领域有通讯需求。两头…

计算机视觉|Swin Transformer:视觉 Transformer 的新方向

一、引言 在计算机视觉领域的发展历程中&#xff0c;卷积神经网络&#xff08;CNN&#xff09; 长期占据主导地位。从早期的 LeNet 到后来的 AlexNet、VGGNet、ResNet 等&#xff0c;CNN 在图像分类、目标检测、语义分割等任务中取得了显著成果。然而&#xff0c;CNN 在捕捉全…

C++单例模式精解

单例模式&#xff08;重点*&#xff09; 单例模式是23种常用设计模式中最简单的设计模式之一&#xff0c;它提供了一种创建对象的方式&#xff0c;确保只有单个对象被创建。这个设计模式主要目的是想在整个系统中只能出现类的一个实例&#xff0c;即一个类只有一个对象。 将单…

【java】集合练习2

Student.java&#xff1a;保存学生类的定义。 public class Student {private String name;private int age;public Student(String name, int age) {this.name name;this.age age;}public String getName() { return name; }public int getAge() { return age; }Overridepu…

FineBI_实现求当日/月/年回款金额分析

需求&#xff1a;原始数据结构如下&#xff0c;需要在分组表中&#xff0c;实现各城市当日/月/年的合同金额分析 实现步骤&#xff1a; ①维度拖入城市 ②分别取当日/月/年合同金额 当日DEF(SUM_AGG(${ 地区数据分析1 _ 合同金额 }),[${ 地区数据分析1 _ 城市 }],[LEFT(${ 地…

【计算机网络】2物理层

物理层任务:实现相邻节点之间比特(或)的传输 1.通信基础 1.1.基本概念 1.1.1.信源,信宿,信道,数据,信号 数据通信系统主要划分为信源、信道、信宿三部分。 信源:产生和发送数据的源头。 信宿:接收数据的终点。 信道:信号的传输介质。 数据和信号都有模拟或数字…

解决PC串流至IPad Pro时由于分辨率不一致导致的黑边问题和鼠标滚轮反转问题

问题背景 今天在做 电脑串流ipad pro 的时候发现了2个问题&#xff1a; 1.ipadpro 接上鼠标后&#xff0c;滚轮上下反转&#xff0c;这个是苹果自己的模拟造成的问题&#xff0c;在设置里选择“触控板与鼠标”。 关闭“自然滚动”,就可以让鼠标滚轮正向滚动。 2. ipadpro 分…