并查集算法

文章目录

  • 并查集
    • 并查集引入
    • 1.初始化
    • 2.查询
    • 3.合并
    • 路径压缩
    • 代码模板
      • (1)朴素并查集:
      • (2)维护size的并查集:
      • (3)维护到祖宗节点距离的并查集:

并查集

并查集引入

并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题。一些常见的用途有求联通子集、求最小生成树的Kruskal算法和求最近公共祖先(LCA)等。

并查集的基本操作主要有:

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

1.初始化

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

假设有编号为1,2,3……,n的n个元素,我们用一个数组fa[]来存储每个元素的父节点。一开始,我们先将它们的父节点设为自己。
在这里插入图片描述

2.查询

找到i的祖先直接返回,未进行路径压缩

int find(int i)
{if(fa[i]==i)//递归出口,当到达了祖先位置,就返回祖先return i;elsereturn find(fa[i]);//不断往上查找祖先
}

3.合并

void unionn(int i,int j)
{int i_fa=find(i);//找到i的祖先int j_fa=find(j);//找到j的祖先fa[i_fa]=j_fa;//i的祖先指向j的祖先。
}

在这里插入图片描述

路径压缩

在这里插入图片描述

int find(int i)
{if(i==fa[i])return i;else {fa[i]==find(fa[i]);//该步进行了路劲压缩return fa[i];//返回父节点}
}

代码模板

(1)朴素并查集:

 	int p[N]; //存储每个点的祖宗节点// 返回x的祖宗节点int find(int x){if (p[x] != x) p[x] = find(p[x]);return p[x];}// 初始化,假定节点编号是1~nfor (int i = 1; i <= n; i ++ ) p[i] = i;// 合并a和b所在的两个集合:p[find(a)] = find(b);

(2)维护size的并查集:

	int p[N], size[N];//p[]存储每个点的祖宗节点, size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量// 返回x的祖宗节点int find(int x){if (p[x] != x) p[x] = find(p[x]);return p[x];}// 初始化,假定节点编号是1~nfor (int i = 1; i <= n; i ++ ){p[i] = i;size[i] = 1;}// 合并a和b所在的两个集合:size[find(b)] += size[find(a)];p[find(a)] = find(b);

(3)维护到祖宗节点距离的并查集:

    int p[N], d[N];//p[]存储每个点的祖宗节点, d[x]存储x到p[x]的距离// 返回x的祖宗节点int find(int x){if (p[x] != x){int u = find(p[x]);d[x] += d[p[x]];p[x] = u;}return p[x];}// 初始化,假定节点编号是1~nfor (int i = 1; i <= n; i ++ ){p[i] = i;d[i] = 0;}// 合并a和b所在的两个集合:p[find(a)] = find(b);d[find(a)] = distance; // 根据具体问题,初始化find(a)的偏移量

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

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

相关文章

设计模式 -- 1:简单工厂模式

目录 代码记录代码部分 代码记录 设计模式的代码注意要运用到面向对象的思想 考虑到紧耦合和松耦合 把具体的操作类分开 不让其互相影响&#xff08;注意这点&#xff09; 下面是UML类图 代码部分 #include <iostream> #include <memory> // 引入智能指针的头文…

Redis底层核心对象RedisObject源码分析

文章目录 1. redis底层数据结构2. 插入KV底层源码流程分析 1. redis底层数据结构 redis 6数据结构和底层数据结构的关系 String类型本质是SDS动态字符串&#xff0c;即redis层面的数据结构底层会有对应的数据结构实现&#xff0c;上面是redis 6之前的实现 redis 7数据结构和底…

关于Nginx服务器配置及性能优化的20道高级面试题

1. 请解释Nginx服务器的工作原理。 Nginx服务器以高性能、稳定性和低资源消耗而著称&#xff0c;其工作原理主要涉及其多进程架构、反向代理功能以及模块组成。具体来看&#xff1a; 多进程架构&#xff1a;Nginx采用一个master进程和多个worker进程的架构。Master进程主要负…

Linux应用程序对异步通知的处理

一. 简介 前面几篇文章学习了 Linux异步通知机制&#xff0c;以及Linux驱动对异步通知部分涉及的内容。文章地址如下&#xff1a; Linux异步通知简介-CSDN博客 Linux驱动中的异步通知机制&#xff1a;信号处理方法-CSDN博客 本文来学习Linux应用程序对异步通知的处理。 二…

[MYSQL数据库]--表的增删查改和字段类型

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、表的增…

高数立体几何笔记

上个学期立体几何章节的一点笔记&#xff0c;很潦草&#xff0c;但重点内容基本都有复习到 Page1&#xff1a;介绍了向量的模、夹角、单位向量、投影投影向量、方向角、点乘、叉乘、混合积的基本运算和性质Page2: 回顾了高中所学的平面直线的多种表示方法以及距离的计算方法&…

Go语言必知必会100问题-21 切片初始化方法及最佳实践

切片初始化 切片使用内置的make函数进行初始化&#xff0c;初始化需要提供两个参数&#xff0c;分别是切片的长度和容量(可选)。如果这两个参数设置的不合理&#xff0c;会使得后续对切片的操作非常低效。下面来看看怎么设置这两个参数是合适的。 假设我们要实现一个转换函数…

【工作实践-07】uniapp关于单位rpx坑

问题&#xff1a;在浏览器页面退出登录按钮上“退出登录”字样消失&#xff0c;而在手机端页面正常;通过查看浏览器页面的HTML代码&#xff0c;发现有“退出登录”这几个字&#xff0c;只不过由于样式问题&#xff0c;这几个字被挤到看不见了。 样式代码中有一行为&#xff1a…

Midjourney绘图欣赏系列(十一)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

Linux常见指令总结

ls&#xff1a;显示当前目录下文件列表 常用的命令行参数&#xff1a; -l 显示更多的文件属性 -a 显示所有的文件/目录&#xff08;包括隐藏的&#xff09; -d 只显示目录 ps&#xff1a;参数可以叠加使用。 例如&#xff1a;ls -la 显示所有文件…

wait 和 notify方法

目录 1.1 wait()方法 wait 做的事情: wait 结束等待的条件: 1.2 notify()方法 1.3notifyAll方法 1.4wait()和sleep()对比 由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知. 但是实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序. 完成这个协调…

利用matlab处理netcdf文件中time变量的格式转换问题

我们通常读取的科研数据具有时间维度&#xff0c;因而通常用于数据运算的时候&#xff0c;最常使用的是&#xff08;2003.567&#xff09;等双精度格式的年份。本专栏提供了一个将nc文件中提供的时间变量的年-月-日转成-年。但是nc文件提供的time变量通常是以下两种格式&#x…

C语言入门学习 --- 2.分支与循环语句

第二章分支与循环语句 2.分支与循环语句 分支语句 ifswitch 循环语句 whiledo whilefor goto语句 2.1分支语句(选择结构) 2.1.1 什么是选择&#xff1f; 例&#xff1a;如果你努力&#xff0c;也许会成功。如果你不努力&#xff0c;你永远不会成功。这就是选择 2.1.2 if语句…

重学SpringBoot3-日志Logging

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-日志Logging 引言默认日志配置日志门面如何实现默认配置 自定义日志配置日志级别日志分组日志格式日志输出自定义 Logback 配置切换日志框架 日志使用方…

数据结构 - 链表 (四)

这篇博客将介绍带头循环的双向链表&#xff0c;实现链表的头部插入/删除&#xff0c;尾部插入/删除&#xff0c;查找&#xff0c;以及任意位置的插入删除。 1.结构 带头循环的双向链表的结构如下图所示&#xff0c;一个结点内部包含数据&#xff0c;以及分别指向前一个以及后…

LabVIEW质谱仪开发与升级

LabVIEW质谱仪开发与升级 随着科技的发展和实验要求的提高&#xff0c;传统基于VB的质谱仪系统已经无法满足当前的高精度和高效率需求。这些系统通常存在着功能不全和操作复杂的问题&#xff0c;影响了科研和生产的进度。为了解决这些问题&#xff0c;开发了一套基于LabVIEW开…

`PF_NETLINK` 是用于与内核通信的Socket族之一

PF_NETLINK 是用于与内核通信的Socket族之一。在Linux系统中&#xff0c;Netlink是一种用于内核与用户空间进程之间通信的机制&#xff0c;而PF_NETLINK Socket族则用于创建与Netlink通信相关的Socket。通过Netlink Socket&#xff0c;用户空间程序可以与内核进行双向通信&…

16. C++标准库

C标准库兼容C语言标准函数库&#xff0c;可以在C标准库中直接使用C语言标准函数库文件&#xff0c;同时C标准库增加了自己的源代码文件&#xff0c;新增文件使用C编写&#xff0c;多数代码放在std命名空间中&#xff0c;所以连接C标准库文件后还需要 using namespace std;。 【…

Python算法题集_搜索旋转排序数组

Python算法题集_搜索旋转排序数组 题33&#xff1a;搜索旋转排序数组1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【二分法区间判断】2) 改进版一【二分找分界标准二分法】3) 改进版二【递归实现二分法】 4. 最优算法5. 相关资源 本文为Pytho…

Qt使用Q_DECLARE_INTERFACE Q_INTERFACES宏实现接口类使用qobject_cast进行类型转换

在写抽象类或者接口的时候&#xff0c;肯定是不能继承QObject的 但是又想使用qobject_cast进行类型转换&#xff0c;使用以下办法就能实现 #ifndef FACTORYINTERFACE_H__ #define FACTORYINTERFACE_H__ #include <QObject> class FactoryInterface{ public:FactoryInterf…