【图论】并查集(Union-find Sets)

news2025/2/23 10:17:47

文章目录

  • 前言
  • 一、并查集(Union-find Sets)
    • 基本概念
    • 基本操作步骤
  • 二、并查集的操作步骤
    • 1. 初始化 `init`
    • 2. 查询 `find`、合并 `union`(未进行路径压缩)
    • 3. 查询 `find`、合并 `union`(路径压缩)
  • 三、Kruskal 算法中 `环` 的判断
    • 并查集的使用
  • 总结


前言

在使用 Kruskal 算法求解最小生成树的时候,需要用到并查集(Union-find Sets),所以记录下并查集的操作与代码。

并查集在最小生成树算法中的使用

并查集的基本概念和基本代码

这两个视频讲解的比较清楚。

一、并查集(Union-find Sets)

基本概念

  • 并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题。一些常见的用途有求连通子图、求最小生成树的 Kruskal 算法和求最近公共祖先(LCA)等。
  • 在无向图中,判断一条边加入后是否形成环可以通过检查该边连接的两个节点是否已经连通来实现。如果这两个节点在加入这条边之前已经是连通的,那么加入这条边后就会形成环。
  • 使用并查集(Union-Find)数据结构来高效地判断两个节点是否连通。并查集支持两种操作:查找(Find)和合并(Union)。查找操作可以确定一个元素属于哪个子集,合并操作可以将两个子集合并成一个子集。

基本操作步骤

  1. 初始化 init
  2. 查询 find
  3. 合并 union

二、并查集的操作步骤

1. 初始化 init

一般初始化时都将每个节点的父亲节点设置为自己

fa = []
def init(n):
    for i in range (1,n+1):
        fa[i]= i

假如有编号为 1 , 2 , 3 , … , n 1,2,3,…, n 1,2,3,,n n n n 个元素,我们用一个数组 f a [ ] fa[ ] fa[] 来存储每个元素的父节点。一开始,我们先将它们的父节点设为自己。

在这里插入图片描述

2. 查询 find、合并 union(未进行路径压缩)

找到 i i i 的父亲节点直接返回,未进行路径压缩:

查询 find

def find(fa, i):
    if fa[i] == i:
        return i
    return find(fa, fa[i])

这是一个递归函数,递归出口是:到达父亲节点位置,就返回父亲节点,否则不断地往上查找父亲节点。

合并 union

def union(fa, i, j):
    # 查找两个节点的父亲节点
    root1 = find(fa, i)  # 找到 i 的父亲节点
    root2 = find(fa, j)  # 找到 j 的父亲节点
    fa[root1] = root2    # 将 i 的父亲节点指向 j 的父亲节点

运行以下代码:

union(4,3)    # 将 4 的父亲节点指向 3 的父亲节点
union(3,2)    # 将 3 的父亲节点指向 2 的父亲节点
union(2,1)    # 将 2 的父亲节点指向 1 的父亲节点

得到:
在这里插入图片描述
若运行union(4,5),意思是将 4 的父亲节点指向 5 的父亲节点。代码中需要不断地 find,查找 4 的父亲节点,直到查找到 4 的父亲节点为 1 ,才将 1 的父亲节点指向 5。

类似于:
在这里插入图片描述
需要查找 3 次,才能查找到父亲节点。

union(4,6) ——— 需要查找 4 次;
union(4,7) ——— 需要查找 5 次;
.
.
union(4,10000) ——— 需要查找 9998 次;

时间复杂度较高。

3. 查询 find、合并 union(路径压缩)

找到 i i i 的父亲节点后,更新 i i i 的父亲节点,进行了路径压缩:

查询 find

def find(fa, i):
    if fa[i] == i:
        return i
    else:
    	fa[i] = find(fa, fa[i])    # 路径压缩
    	return fa[i]

合并 union

def union(fa, i, j):
    # 查找两个节点的父亲节点
    root1 = find(fa, i)  # 找到 i 的父亲节点
    root2 = find(fa, j)  # 找到 j 的父亲节点
    fa[root1] = root2    # 将 i 的父亲节点指向 j 的父亲节点

运行以下代码:

union(4,3)    # 将 4 的父亲节点指向 3 的父亲节点
union(3,2)    # 将 3 的父亲节点指向 2 的父亲节点
union(2,1)    # 将 2 的父亲节点指向 1 的父亲节点

得到:

在这里插入图片描述
若运行union(4,5),意思是将 4 的父亲节点指向 5 的父亲节点。因为在之前的代码中已经将 4 的父亲节点更新为 1,所以直接将 1 的父亲节点指向 5 ,代码就运行结束了。

三、Kruskal 算法中 的判断

  • 在 Kruskal 算法中,初始化每个节点为一个独立的树(父亲节点都是自己,互不相同)。

  • 那么如何判断加入一条边后会不会形成环呢?

    • 如果这条边的两个节点属于两棵不同的树,那么加入后一定不会形成环(父亲节点不相等,就不会形成环);
    • 如果这条边的两个节点属于同一棵树,那么加入后就会形成环(父亲节点相等,就会形成环)。
  • 所以判断加入一条边后会不会形成环,只需要判断这条边的两个节点的父亲节点是否相等即可。

并查集的使用

  1. 初始化所有节点的父亲节点
  2. 查找其两个节点的父亲节点
  3. 若父亲节点不相等,则将该边加入;若相等,则舍去

总结

本文介绍了并查集(Union-find Sets)的基本概念和用法,并且解释了为什么要在 find 函数中进行路径压缩。简单介绍了如何使用并查集判断是否形成 “环”。

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

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

相关文章

C++中的string介绍(常用函数)

string类 为什么学习string类C语言中的字符串 标准库中的string类string类(了解)auto和范围forauto关键字范围for string类的常用接口说明(注意下面只讲解最常用的接口)string类对象的常见构造 string类对象的容量操作string类对象的访问及遍历操作string类对象的修改操作strin…

洛谷 P6280 [USACO20OPEN] Exercise G

题目来源于:洛谷 题目本质:dp,素数筛法,质数 本题与P4161基本一模一样 首先,分析题目发现,某个排列的需要进行恰好 K 步变回原样,这个时候K的值就是这个排序中各个环的长的的最小公倍数(lcm)。…

wechatAssetsPicker组件的用法

文章目录 1. 概念介绍2. 思路与方法2.1 使用思路2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"ImagePicker使用总结"相关的内容,本章回中将介绍wechat_assets_picker这个三方包.闲话休提,让我们一起Talk Flutter吧。 1. 概念介…

红外遥控设计验证

前言 红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机和手机系统中。本文…

位运算(1)

1.获取第i位的二进制数(只出现一次数字2): 2.将第i位的二进制设为1(只出现一次数字2): 3.int最低位为1的数(只出现一次数字3):

【2024】docker镜像拉取失败网络超时解决办法-自建镜像加速服务

目录 前言一、直接配置镜像加速地址二、自己搭建中转服务进行镜像加速1、Fork副本2、创建cloudflare3、注册域名4、测试使用5、配置变量 前言 近期docker官方镜像拉取经常容易出现网络超时,下面为一些常用的处理解决部分 实现docker镜像拉取加速解决方案 直接使用一…

【iOS】Block底层分析

目录 前言Block底层结构Block捕获变量原理捕获局部变量(auto、static)全局变量捕获实例self Block类型Block的copyBlock作为返回值将Block赋值给__strong指针Block作为Cocoa API中方法名含有usingBlock的方法参数Block作为GCD API的方法参数Block属性的写…

[第五空间 2021]EasyCleanup

题目源代码&#xff1a; <?php if(!isset($_GET[mode])){ highlight_file(__file__); }else if($_GET[mode] "eval"){ $shell isset($_GET[shell]) ? $_GET[shell] : phpinfo();; if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit(&q…

git学习使用碰到的问题1

本来在B站上看到的关于stash的使用时视频末尾讲到git stash drop 编号 会删除暂存记录 确实也是这么回事&#xff0c;但是末尾说到git stash pop 编号时up主说在恢复工作进度的时候我们可以直接删除掉这个工作记录可以直接使用 git stash pop stash{0} 使用完以后却出现了如上图…

AI项目二十四:yolov10竹签模型,自动数竹签

若该文为原创文章&#xff0c;转载请注明原文出处。 原本是为部署RK3568而先熟悉yolov10流程的&#xff0c;采用自己的数据集&#xff0c;网上很多&#xff0c;检测竹签&#xff0c;并计数。 1、环境搭建 1.1 官方下载源码 官网地址&#xff1a;YOLOv10 gitbub官网源码 利用…

各类函数调用

目录 getpwuid函数 查看uid的name​编辑 symlink函数软链接&#xff08;创建快捷方式&#xff09; remove函数 rename函数 link硬链接 truncate函数控制文件大小 perror报错函数 strerror报错函数序列表 error报错函数&#xff1a;详细报错 Makefile编译函数、工程管…

考试题型宏观分析之公共营养师三级

背景 第一遍知识学习之后&#xff0c;打印《2023.10.14公共营养师三级真题》进行第一次摸底&#xff0c;首要目标在于通过摸底&#xff0c;对于考试题型进行宏观分析和了解&#xff0c;其次&#xff0c;对于后续的学习进行有的放矢 直至2024-08-18&#xff0c;对于上述资料的一…

ubuntu配pip的源

临时使用源 pip install [包名] -i [pip源URL]# 示例 pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple更换配置pip镜像源 step1&#xff1a;创建一个配置文件 mkdir ~/.pip/ cd .pip sudo vim pip.conf step2:填写源信息&#xff0c;保存并退出【:wq】 [g…

Android 架构模式之 MVC

目录 架构设计的目的对 MVC 的理解Android 中 MVC 的问题试吃个小李子ViewModelController 大家好&#xff01; 作为 Android 程序猿&#xff0c;MVC 应该是我们第一个接触的架构吧&#xff0c;从开始接触 Android 那一刻起&#xff0c;我们就开始接触它&#xff0c;可还记得我…

【秋招笔试】8.18科大讯飞秋招-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…

【接口测试】Postman + newman超详细图文安装教程

一、Postman安装 下载网址&#xff1a;Postman API Platform 打开网址&#xff0c;选择自己系统对应的版本进行下载。 双击Postman安装包&#xff0c;全自动安装&#xff0c;不需要任何人为干预。安装完成后&#xff0c;页面如下图&#xff0c;点击手动打开注册页面。 自行…

超详细!!!electron-vite-vue开发桌面应用之引入UI组件库element-plus(四)

云风网 云风笔记 云风知识库 一、安装element-plus以及图标库依赖 npm install element-plus --save npm install element-plus/icons-vue npm i -D unplugin-icons二、vite按需引入插件 npm install -D unplugin-vue-components unplugin-auto-importunplugin-vue-componen…

Linux-DNS域名解析服务

系列文章目录 提示&#xff1a;仅用于个人学习&#xff0c;进行查漏补缺使用。 1.Linux网络设置 2.LinuxDHCP服务 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言提示&#xff1a;以下是本篇文章…

扫描切除-实体轮廓:方程式驱动曲线路径vs螺旋线路径

最近,在使用solidworks2018的过程中,接触到扫描切除-实体轮廓命令,如图1-2所示。此命令可以使用一个实体来切除另一个实体,用来切除的实体可以按一定的轨迹运动。测试过程中发现,这个命令频繁出错,切除失败,体验实在是太差了。下面对比了在该命令下使用方程式驱动曲线和…

后端学习笔记(八)--HTML

1.HTML ​ *编写网页的一门语言 ​ *HTML(HyperText Markup Language)&#xff1a;超文本标记语言 ​ *超文本&#xff1a;超越了文本的限制&#xff0c;比普通文本更强大。除了文字信息&#xff0c;还可以定义图片、音频、视频等内容 ​ *标记语言&#xff1a;由标签构成的…