目录

 引言

简单介绍

        浅浅总结

算法图解

初始化

根节点查找

集合合并

连通性检查

例题

大概思路

完整代码:


 引言

一个小小的并查集让我们在ccpc卡了那么久(还有unordered_map,如果不是忘了map自动排序这么一回事也不至于试那么多发),至今仍然心有余恨。所以期末结束的第一件事就是拿下这个可恶的并查集!并狠狠的写一篇博客来纪念它的祭日!(6.27 R.I.P.)废话不多说,下面开始正题:


简单介绍

        单看“并查集”这个名字可能没什么概念,它的英文名(Union-Find) 可能还稍微好理解一点。看看官方一点的描述 (豆包生成^_^):

        并查集算法(Union-Find Algorithm),又称不相交集合联合算法(Disjoint Set Union, DSU),是一种用于管理若干不相交集合的高效数据结构,支持以下核心操作:

  1. 初始化(Initialize):将每个元素初始化为独立集合,每个集合的代表元(根节点)为自身。
  2. 查找(Find):确定某个元素所属的集合,返回该集合的代表元(根节点)。
  3. 合并(Union):将两个不同的集合合并为一个集合。
浅浅总结

        并查集算法的设计目标是高效处理集合的动态合并与查询问题,其核心思想是通过树形结构表示集合,每个节点存储其父节点信息,根节点作为集合的标识。


算法图解

初始化

可以把整个看作一个大树,最开始它们的根都是它们自己。这一步要进行初始化~

void init(int n)
{parent.resize(n+1);Size.resize(n+1,1);//初始化 刚开始他们的父节点都是自己for(int i=0; i<=n; i++) parent[i]=i;
}

根节点查找

        我们进行一些合并的操作,比如下边这个的东西,就是经过一些小的合并操作之后的结果。那么如果此时我们想看某两个元素是否在同一棵树上该怎么搞呢?那么我们只需要看它们的根节点是否相同就行了。比如此时想判断10和3是否属于一棵树,那么分别找它们的根节点并判断就行了。例:10->4->6,3->4->6。代码就像这样:

int find(int x) {while (parent[x] != x) {x = parent[x];  // 逐级向上查找根节点}return x;  // 返回根节点
}

        这样的话逻辑上来说好像确实没毛病,但是实际操作之后发现当节点数量足够多的时候,每次查找都要从子节点一点一点朝根节点寻找,效率非常的慢,极其容易超时。仔细再想一下,其实我们不需要树上的其他关系,似乎只需要确定子节点是否属于根节点就行了。那么如果我们直接将树的所有子节点连到根节点上,每次查找的时候就只需要O(1)就可以解决。就像下图:

代码改进:

int find(int x)//寻找根节点
{if(parent[x]!=x)//路径压缩,将路径上的节点直接连接到根节点上parent[x]=find(parent[x]);return parent[x];
}

集合合并

        然后再说一下合并的环节。合并的时候不要直接将两个节点连接,这样的话会增加树的高度。合并这个操作对我们的作用就是这俩点所连的所有节点都同属于一棵树,我们直接把它们的根节点连接就行。还有一个问题就是这俩树该哪个连到哪个上边。由于相连之后主动连接的树上所有点的根节点都需要发生变化,所以我们将小树连到大树上,这样的话可以减小工作量。同时统计树大小的Size数组还可以表示此时元素所在树的节点多少。代码:

void unit(int x, int y)//合并集合
{x = find(x);//找根节点y = find(y);if(x==y) return ;//根节点一样就不用连了if(Size[x]<Size[y])//将高度小的树连到高度大的树上{parent[x]=y;Size[y]+=Size[x];}else//合并然后数量相加{parent[y]=x;Size[x]+=Size[y];}
}

连通性检查

然后就是判断操作,用来看是否两个节点可以互通(根节点相同)。只需find函数查找一下就行了

//检查两个节点是否同属一个集合(根节点是否相同)
bool connected(int x, int y)
{return find(x)==find(y);
}

例题

 大概就是这个样子了,本算法还是相对模板的,但也很妙!以一道题为例吧:P1111 修复公路 - 洛谷https://www.luogu.com.cn/problem/P1111


大概思路

        主线还是进行集合合并以及判断是否全部联通。需要注意的是它要求最快什么时候能全部联通。那么我们就要对修路操作根据时间进行排序。先用结构体将修路信息储存起来并按时间升序排序并逐次判断连通性。如果此时全部联通,直接输出此时时间并退出程序。

完整代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+5;
const int M = 1e5+5;
#define int long long
vector<int> parent;
vector<int> Size;
int x,y,t;
int n,m;
struct site
{int a;//连接的两个村庄int b;int t;//修通的时间
}f[M];bool cmp(site a, site b)
{return a.t < b.t;
}void init()
{parent.resize(N);Size.resize(N,1);//初始化 刚开始他们的父节点都是自己for(int i=0; i<N; i++) parent[i]=i;
}int find(int n)//寻找根节点
{if(parent[n]!=n)//路径压缩,将路径上的节点顺手连到根节点parent[n]=find(parent[n]);return parent[n];
}void unit(int x, int y)//将两点联通
{x = find(x);y = find(y);if(x==y) return ;//如果根节点一样就不用链接了if(Size[x]<Size[y])//将小树连到大树上{parent[x] = y;Size[y]+=Size[x];//合并之后数量相加}else{parent[y] = x;Size[x]+=Size[y];}
}bool lian(int x, int y)//判断根节点是否相同
{return find(x)==find(y);
}void solve()
{cin >> n >> m;//村庄数量和公路数量init();//先初始化for(int i=1; i<=m; i++)//先将路径用结构体存起来{cin >> x >> y >> t;f[i].a=x;f[i].b=y;f[i].t=t;}sort(f+1,f+1+m,cmp);//根据修通的时间升序排序int f1=0;for(int i=1; i<=m; i++){unit(f[i].a,f[i].b);if(Size[find(f[i].a)]==n)//如果此时已经将所有的村庄都链接起来了{cout << f[i].t;//就直接是最早时间f1=1;return ;}}if(!f1) cout << -1;//所有路都修完了但是还没有全部通路
}signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int t=1;// cin >> t;while(t--) solve();return 0;
}

OK到这里就结束了,图画的比较简陋,凑合看吧。终于解我心头之恨,爽!不过也说明实在太菜了,当时这都没学到 --_--

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

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

相关文章

书籍在行列都排好序的矩阵中找数(8)0626

题目&#xff1a; 给定一个有N*M的整型矩阵matrix和一个整数K&#xff0c;matrix的每一行和每一列都是排好序的。实现一个函数&#xff0c;判断K是否在matrix中。 0 1 2 5 2 3 4 7 4 4 4 8 5 …

深度学习04 卷积神经网络CNN

卷积神经网络与人工神经网络关系与区别 概念 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;是人工神经网络&#xff08;Artificial Neural Network, ANN&#xff09;的一种特殊形式&#xff0c;两者在核心思想和基础结构上存在关联&#xff0c;但在…

vue基础之组件通信(VUE3)

文章目录 前言一、父子组件通信1.父组件向子组件通信2.子组件向父组件通信3.ref父组件直接操作子组件通信。 二、跨代通信1. 跨层级通信2.事件总线通信 总结 前言 vue3的组件通信和vue2相比在语法上会有些差距&#xff0c;且vue3有的通信方式也在功能上比vue2更加完善&#xf…

【RidgeUI AI+系列】中文重复统计器

中文重复统计器 文字重复统计是一个使用文本处理工具&#xff0c; 输入文本内容并指定最小词长度后&#xff0c; 就能自动高亮显示重复的词。 本教程将会借助AI实现这个应用的开发 页面脚本编写 该工具的基础流程较为清晰&#xff1a;用户输入一段文字后&#xff0c;调用提取…

代码随想录|图论|05岛屿数量(深搜DFS)

leetcode:99. 岛屿数量 题目 题目描述&#xff1a; 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成&#xff0c;并且四周都是水域。你可以假设矩阵外均…

数据结构-第二节-堆栈与队列

一、概念&#xff1a; 堆栈与队列也是线性表&#xff0c;但是&#xff1a; 堆栈&#xff1a;只能在一个端进行插入删除&#xff0c;此端称为栈顶。&#xff08;特点&#xff1a;后来居上&#xff09; 队列&#xff1a;在一端进行插入&#xff08;队尾&#xff09;&#xff0…

HarmonyNext动画大全02-显式动画

HarmonyOS NEXT显式动画详解 1. 核心接口 显式动画通过animateTo接口实现&#xff0c;主要特点包括&#xff1a; 触发方式&#xff1a;需主动调用接口触发动画 参数配置 &#xff1a; animateTo({duration: 1000, // 动画时长(ms)curve: Curve.Ease, // 动画曲线delay: 200…

芯谷科技--高压降压型 DC-DC 转换器D7005

在当今电子设备日益复杂且对电源性能要求极高的背景下&#xff0c;一款高效、稳定的电源管理芯片至关重要。 D7005凭借其卓越的性能和广泛的应用适配性&#xff0c;成为众多工程师在设计电源方案时的优选。 产品简介 D7005 是一款高效、高压降压型 DC-DC 转换器&#xff0c;具…

MySQL的GTID详解

GTID&#xff08;Global Transaction Identifier&#xff0c;全局事务标识符&#xff09;是MySQL 5.6及以上版本引入的重要特性&#xff0c;用于在主从复制环境中唯一标识每个事务&#xff0c;简化复制管理、故障转移和数据一致性维护。以下从多维度详细介绍GTID&#xff1a; …

专题:2025中国游戏科技发展研究报告|附130+份报告PDF、原数据表汇总下载

原文链接&#xff1a;https://tecdat.cn/?p42756 本报告汇总解读基于艾瑞咨询《2025中国游戏科技发展白皮书》、伽马数据《2025年1-3月中国游戏产业季度报告》、嘉世咨询《2025中国单机游戏市场现状报告》等多份行业研报数据。当《黑神话&#xff1a;悟空》以虚幻引擎5复刻东…

【数据挖掘】数据挖掘综合案例—银行精准营销

要求&#xff1a; 1、根据相关的信息预测通过电话推销&#xff0c;用户是否会在银行进行存款 2、数据bank.csv&#xff0c;约4520条数据&#xff0c;17个属性值 提示&#xff1a; 17个属性&#xff0c;分别是年龄&#xff0c;工作类型&#xff0c;婚姻状况&#xff0c;受教育…

postgresql查看锁的sql语句

发现一个查看postgresql锁比较好的sql语句&#xff0c;参考链接地址如下 链接地址 查看锁等待sql witht_wait as(select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.trans…

JSON 格式详解

JSON 格式详解 随着互联网的发展和各种 Web 应用程序的普及&#xff0c;数据交换已经成为了我们日常开发中的重要环节。而在各种数据交换格式中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&#xff0c;以其简洁、易于阅…

原型设计Axure RP网盘资源下载与安装教程共享

对于初学者来说&#xff0c;我们熟悉一下其定义&#xff1a;‌Axure RP是一款常用的快速原型设计工具‌&#xff0c;主要用于创建应用软件或Web网站的线框图、流程图、原型和规格说明文档&#xff0c;广泛应用于产品经理、UI/UX设计师等专业领域。‌‌ 主要用户群体&#xff1…

iframe嵌套 redirect中转页面 route跳转

需求是项目A要使用iframe内嵌项目B的页面&#xff0c; 由于需要嵌套的页面很多&#xff0c;每个页面路径和参数又各不相同&#xff0c; 所以我们在项目B里做了一个中转页面&#xff0c;这样就能自己掌控项目A传递过来的东西了&#xff1b; routes.js 增加一个菜单&#xff1a;…

IP数据报 封装成 MAC帧 ( 目的MAC地址6B 源MAC地址6B 类型2B 数据部分 FCS校验和4B )

将 IP 数据报&#xff08;Internet Protocol Datagram&#xff09;封装成 MAC 帧 需要在数据链路层添加适当的头部信息&#xff0c;以便在局域网内进行传输。这个过程涉及将网络层&#xff08;IP 层&#xff09;的数据通过数据链路层&#xff08;MAC 层&#xff09;封装成适合物…

Note2.4 机器学习:Batch Normalization Introduction

Batch Normalization&#xff08;批标准化&#xff0c;BN&#xff09;通过标准化数据的操作&#xff0c;使得损失函数的优化地形&#xff08;optimization landscape&#xff09;更加平滑&#xff0c;从而达到更好地训练效果。BN常用于卷积神经网络&#xff08;CNN&#xff09;…

IDEA在AI时代的智能编程实践:从工蜂到通义灵码的效能跃迁‌‌

引言‌ 在腾讯云工作期间&#xff0c;我曾使用‌工蜂的AI代码补全功能&#xff0c;结合IntelliJ IDEA&#xff08;以下简称IDEA&#xff09;极大提升了开发效率。如今离开腾讯云&#xff0c;面对外部开发环境&#xff0c;如何继续利用AI提升编码效率&#xff1f;本文将系统梳理…

MySQL 慢查询日志详解

慢查询日志&#xff08;Slow Query Log&#xff09;是 MySQL 提供的一种核心性能优化工具&#xff0c;用于记录执行时间超过指定阈值的 SQL 语句。通过分析这些日志&#xff0c;可以定位数据库性能瓶颈&#xff0c;优化低效查询&#xff0c;提升系统整体效率。 一、慢查询日志的…

UV安装Python指南总结

UV安装Python指南总结 UV是一个Python包管理工具,它可以帮助我们安装和管理Python版本。以下是关于UV安装Python的主要功能和用法总结。 基本使用 安装最新版Python uv python install注意&#xff1a;UV使用Astral的python-build-standalone项目提供的Python发行版,而不是…