【算法专题】图论专题:并查集

ACM算法竞赛进阶指南:从入门到精通的系统性学习路径 本文系统性地介绍了ACM算法竞赛从入门到精通的学习路径,涵盖基础算法、数据结构、图论、动态规划和数学专题等核心内容。通过实战案例和训练方法,帮助竞赛选手高效提升解题能力,特别适合准备ACM竞赛的选手参考学习。 阅读详情


并查集 是一种树型的数据结构,用于处理一些不相交集合的合并和查询问题。在使用中常常以森林来表示。

基本结构

并查集也是用来维护集合的,和前面学习的 set 不同之处在于,并查集能很方便地同时维护很多集 合。如果用 set 来维护会非常的麻烦。并查集的核心思想是记录每个结点的父亲结点是哪个结点。

  • 初始化
void init() {    
 for (int i = 1; i <= n; ++i) {        
  fa[i] = i;     
  } 
  }
  • 查找
int get(int x) {     
if (fa[x] == x) { 
// x 结点就是根结点         
return x;     
}   
return get(fa[x]); // 返回父结点的根结点 }
  • 合并
void merge(int x, int y) {     
x = get(x);     
y = get(y);    
 if (x != y) { // 不在同一个集合       
   fa[y] = x;     
 }
 }

并查集实现

首先,我们把要用的变量初始化。

int fa[110]; 
int n, m;

我们先把并查集的框架实现好,便于后面直接调用。我们先实现初始化,用一个 init() 函数来实现初 始化。初始化实际上就是把每个点的父亲结点赋值为自己。

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

接下来,我们继续实现get函数

int get(int x) {     
if (fa[x] == x) {         
return x;     
}     
return get(fa[x]); 
}

接下里我们实现 merge 函数,合并两个结点到一个集合。合并的方法很简单,先找到各自的根结点, 如果根结点不相同,让其中一个根结点的父亲变成另外一个根结点。

void merge(int x, int y) {    
 x = get(x);    
  y = get(y);    
   if (x != y) {         fa[y] = x;    
    } 
    }

这一步我们接收输入,在接收一组关系以后,我们通过 merge 合并他们到一个集合。注意,在这之 前,我们需要先初始化并查集。初始化要在 输入之后,这是平时写程序很容易错误的一个点。 在 main 函数里面写下

cin >> n >> m;
 init(); 
 for (int i = 0; i < m; i++) {     
 int a, b;    
 cin >> a >> b;     
 merge(a, b); 
 }

最后我们统计几何的个数。统计方法很简单,只需要统计集合的根结点的数量。

int cnt = 0; 
for (int i = 1; i <= n; i++) {    
 if (fa[i] == i) {        
  cnt++;    
   }
   } 
  cout << cnt << endl; 

最后,再来看一看运行一下,看一看结果。

6 4 1 2 2 3 1 3 4 5 

路径压缩

并查集的时间复杂度很高,最坏可以达到O(n),所以,我们更适用于路劲压缩的并查集,这一回,就来给大家讲一讲路劲压缩后的并查集。
路径压缩 的思想是,我们只关心每个结点所在集合的根结点,而并不太关心树的真正的结构是怎么样 的。这样我们在一次查询的时候,可以直接把查询路径上的所有结点的 都赋值成为根结点。实现 这一步只需要在我们之前的查询函数上面进行很小的改动。

int get(int x) {     
if (fa[x] == x) { 
// x 结点就是根结点         
return x;     
}     
return fa[x] = get(fa[x]); // 返回父结点的根结点,并令当前结点父结点直接为根结点 
}

下面是进过比较的并查集(右图为路径压缩)
在这里插入图片描述

联通性

之前我们判断无向图的连通性的时候(有向图的连通性我们会在之后的课程介绍),用的是 DFS 的方 法。而用并查集来判断无向图的连通性,只需要把每一条边连接的两个点合并到一个集合就可以了,都 不必存图,最后如果集合个数为 ,说明整个图是连通的。

路径压缩的实现
#include <iostream> 
using namespace std; 
int fa[110];
 int n, m; 
 void init() {    
  for (int i = 1; i <= n; i++) {        
   fa[i] = i;     
   } 
   } i
   nt get(int x) {    
    if (fa[x] == x) {        
     return x;    
      }     
      return get(fa[x]); 
      } 
      void merge(int x, int y) {    
       x = get(x);     
       y = get(y);    
        if (x != y) {        
         fa[y] = x;     
         } 
         } 
         int main() {     
         cin >> n >> m;     
         init();     
         for (int i = 0; i < m; i++) {        
          int a, b;         
          cin >> a >> b;        
           merge(a, b);     
           }     
           int cnt = 0;    
            for (int i = 1; i <= n; i++) {         
            if (fa[i] == i) {             
            cnt++;         
            }    
             }     
             cout << cnt << endl;     
             return 0;
              }

看一看结果

6 4 1 2 2 3 1 3 4 5

种类并查集

种类并查集是借助借助并查集来解决一系列种类查询问题。
问题描述如下,有 个人,我们不知道每个人的性别,但是有 组关系,每一组关系表示 和 是同 性或者异性,问这 组关系是否有矛盾。
这个问题,可以二分图判定来做,这里我们学习带权并查集的解法。每个点的权值我们规定只用 和 两个值,用 表示这个点和父结点同性,用 表示这个点和父结点是异性。那么在查询的时候,我们 之需要把权值对 取模。比如 和 异性, 和 异性,那么 和 同性。
在这里插入图片描述

int get(int x) {     
if (fa[x] == x) {        
 return x;     
 }    
  int y = fa[x];    
   fa[x] = get(y);     
   dist[x] = (dist[x] + dist[y]) % 2;     
   return fa[x];
 }

我们知道 和 的关系和 和 的关系,就可以计算出 和 的关系等于 和 和关系减去 和 的 关系,也就是 。
而如果 和 不属于同一个集合,说明他们之前的关系,假设他们现在的关系为 。这时候,我们合并 他们,这时候他们的关系如下图。

在这里插入图片描述

void merge(int a, int b, int d) {     
int x = get(a);    
int y = get(b);     i
f (x == y) {        
 // 同一集合,已知关系         
 if ((dist[a] - dist[b] + 2) % 2 != d) {             
 // 加上 2 再对 2 取模防止出现负数             
 cout << "No" << endl;        
  }     
  } else {        
   // 未知关系         
   fa[x] = y;         
   dist[x] = (dist[b] - dist[a] + d + 2) % 2;   
   } 
   }

多种关系种类并查集

用 表示和父结点平手, 表示战胜父结点, 表示被父结点战胜。这时候权值应该对 取模。而合并的时候权值的关系还是参考之前的两个图。
在这里插入图片描述

蓝桥杯研究生Python组备赛全攻略:从基础到实战 本文为研究生备战蓝桥杯Python组提供了一份从零基础到实战的全方位攻略。内容涵盖高效入门Python、掌握核心算法与数据结构、制定科学的刷题策略以及临场应试技巧,旨在帮助研究生选手系统备赛,提升竞赛成绩。 阅读详情

相关推荐

Acwing算法基础课:从零到机试高分的系统学习路线与实战笔记

本文系统介绍了如何利用Acwing算法基础课高效备考机试。课程内容从基础算法、数据结构到动态规划,提供了清晰的模块化学习路线和实战笔记。文章强调通过系统学习和模板化练习,掌握算法核心,并分享了从零到高分的学习规划、核心模块拆解及应试技巧,帮助计算机专业学生有效提升算法能力与机试成绩。

orange的博客 308

通俗易懂的并查集解释(附简单代码)

碰巧在学习kruskal算法来实现最小生成树,其中用到了并查集,然后详细研究了并查集。找到一篇好的链接。原文链接参考:https://blog.youkuaiyun.com/qq_41593380/article/details/81146850 具体并查集解释参考链接。代码如下: #include<iostream> #include<cstdio> #include&lt...

aishuirenjia的博客 485

图论基础和图论算法

图论基础 图的基础知识 图论的基本研究对象,图由节点和边组成。 节点 图二、图二中黑色的圆圈就是节点,表示某个事物或对象。 边 图二、图二中顶点之间灰色的线条就是边,表示事物与事物之间的关系。 权值 权值,即每条边都有与之对应的值。例如当顶点代表某些物理地点时,两个顶点间边的权重可以设置为路网中的开车距离(例如:从北京到上海的铁路1300km,从上海到重庆的铁路1600km,这里就是分别把北京、...

洛谷棕名用户的博客(兔子的博客) 1160

新手适用“并查集“简单教学

这里写自定义目录标题并查集的概念并查集的适用情况介绍根,父结点与子结点,深度。(图)基本函数1.初始化2.找根(找每一个传过来的元素的根)3.连接4.主函数运行结果作者学会以后自己写的并查集源码 并查集的概念 在计算机科学中,并查集是一种树形的数据结构,用于处理不交集的合并(union)及查询(find)问题。可用于查询网络中两个节点的状态,这里的网络是一个抽象的概念, 不仅仅指互联网中的网络, 也可以是人际关系的网络、交通网络,路径关系等。 并查集 除了可以用于查询 网络 中两个节点的状态, 还可以用于数

qq_55726549的博客 403

数据结构专题系列 基础篇-1 并查集

数据结构专题系列 基础篇-1 并查集

weixin_41801682的博客 1608

【算法学习】图论专题 判断无向图中环的存在、环的输出

文章目录一、无向图 Detect Cycle in a Undirected Graph1. DFS(1) 判断环的存在(2) 输出环路2. BFS(1) 判断环的存在3. Union-Find(1) 原理讲解(2) 代码实现二、有向图 Detect Cycle in a Directed Graph1. Detect Cycle in a Directed GraphDetect Cycle in a Directed Graph using BFSDetect Cycle in a directed g

memcpy0的博客 1万+

并查集

并查集主要用来解决: (1)一群节点有分为几个集合问题。(朋友圈) (2)判断两个点是不是在一个集合里。 (3)判断一个图里是不是有环。 并查集思路: (参考bilibili的博主例子,为了查阅方便,记录下来。) 背景:我们想要判断以下图中是不是有环的问题。先构造出以下场景。 int connected[6][2] = {{0, 1}, {1, 2}, {1, 3}, {2, 3}, {3, 4}, {2, 5}}; 其他场景的连线问题也是万变不离其宗。 可能会遇见不是整型,而是字符串的形

qq_34008220的博客 677

第三节: 串口通信(用CubeMX学习STM32)

用CubeMX学习STM32, 串口通信学习, 通过轮询方式和中断方式两种方式进行通信演示。 STM32F407zgt6

Kevin_8_Lee的博客 8904

并查集&带权并查集

最开始接触并查集是在学Kruskal算法时,今天主要学了带权并查集,记录下来我的一些理解和做题套路。 首先贴大佬博客Orz: 模板代码及详解:https://blog.youkuaiyun.com/Chris_zzj/article/details/52227656 典型例题及代码:https://blog.youkuaiyun.com/tribleave/article/details/72878239 我对带...

A confused programmer 560

手把手教你用ADS和CGH40010F模型搭建Doherty功放仿真原型(附工程文件)

本文详细介绍了如何使用ADS软件和CGH40010F GaN器件模型搭建Doherty功放仿真原型,涵盖工程准备、关键电路模块实现、效率优化技巧及常见问题排查。通过实战指南和效率优化技巧,帮助工程师快速掌握Doherty功放设计,提升5G基站和广播发射系统的功率放大器性能。

weixin_26897585的博客 344

QT/C++实现健壮HTTP POST客户端:从基础到异常处理与性能优化

HTTP协议作为客户端与服务器通信的基石,其POST方法在数据提交、API交互等场景中扮演着核心角色。其工作原理基于请求-响应模型,通过封装TCP连接与协议细节,为应用层提供了简洁的数据传输接口。在C++桌面与嵌入式开发中,直接使用底层Socket实现HTTP不仅复杂且易出错,而利用框架进行高级封装能显著提升开发效率与代码健壮性。QT框架的`QNetworkAccessManager`等组件正是为此设计,它通过信号槽机制提供异步网络编程模型,有效管理连接与协议解析。一个健壮的HTTP客户端需要妥善处理网络波

weixin_29176179的博客 384

代码随想录算法训练营第五十六天|图论专题: 并查集,108. 冗余连接、109. 冗余连接2

,这说明在两条边都可以删除的情况下,要删顺序靠后的边!我们来想一下 有向树的性质,如果是有向树的话,只有根节点入度为0,其他节点入度都为1(因为该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点)。

weixin_44061719的博客 383

Shell编程规范及变量

文章目录一.Shell脚本1.1Shell概述1.2Shell脚本 一.Shell脚本 1.1Shell概述 Shell是Linux系统中开机自动加载的一个特殊程序,它将用户输入的指令,转换成Linux内核可以识别的语言,从而让内核执行调用硬件。 Bash是Linux系统中默认使用shell的程序,它位于/bin/bash。 1.2Shell脚本 将需要执行的命令保存到一个文件中,按照顺序执行,它不需要编译,它是解释型的 ...

夏颜的博客 3674

代码随想录算法训练营第五十五天|图论专题: 并查集理论基础、107. 寻找存在的路径

通过模板,我们可以知道,并查集主要有三个功能。

weixin_44061719的博客 290

【PCIe】CDNS PCIe VIP 杂记 -- Callback

最近在研究Cadence PCIe VIP,怎一个“惨淡”来描述。用的真是一言难尽啊,都是泪。记录一些最近学习的觉得想记录的内容在此,仅供参考讨论学习哈。有不对之处请指出大家一起讨论。

小邦是名小ICer的博客 2716

18、基于FSDD数据集的深度学习案例分析

本文基于FSDD(Free Spoken Digit Dataset)数据集,系统介绍了深度学习在语音数字识别中的应用。内容涵盖动态与静态计算图的对比、数据预处理流程(包括数据增强、固定长度处理和归一化)、监督学习与无监督学习的模型构建与训练过程,并通过实验对比了不同网络架构的性能。文中使用PyTorch实现2层全连接网络和自编码器模型,展示了正则化技术对提升模型准确率的关键作用。最后总结了关键技术并提出了实际应用建议,展望了未来在复杂模型、多模态融合和实时应用方向的发展潜力。

vscode6remote的博客 259

图论专题(二十):并查集的“破冰”之旅——搞定「省份数量」

虽然这道题完全可以用 DFS 或 BFS 解决(类似“岛屿数量”,遍历每个城市,把它能到的所有城市标记为已访问,计数+1),但并查集初始状态:假设有n个城市,起初它们互不相通,所以有n个省份。每个城市自己就是自己的“老大”。处理连接:当我们发现时,这意味着i和j应该属于同一个省份。合并 (Union):如果i和j原本不属于同一个阵营,我们就把它们的阵营合并。每次合并成功,省份的总数量就减 1。最终结果:遍历完所有连接后,剩下的省份数量就是答案。今天,我们掌握了图论中处理“连通性”的最强工具——并查集。

2301_80334067的博客 1102

11. 使用 HTTP PUT, PATCH 以及 MERGE 请求消费 SAP ABAP OData 服务修改操作的实现及其区别

使用 SAP ABAP SEGW 事物码实现 OData 服务的修改操作时,对于消费端通过 PATCH/MERGE 和 PUT 这三种不同类型的 HTTP 请求触发的场景,我们应该在 UPDATE_ENTITY 方法里用 IF 分支分别进行处理,原因就在于 GET_ENTITY 方法是否在修改处理逻辑的过程中被触发。......

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2457

leetcode(图论专题)

图论1.导论2.编程题2.1 127. 单词接龙 1.导论 2.编程题 2.1 127. 单词接龙 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列: 序列中第一个单词是 beginWord 。 序列中最后一个单词是 endWord 。 每次转换只能改变一个字母。 转换过程中的中间单词必须是字典 wordList 中的单词。 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到

Listen·Rain的博客 2155

80、编程学习资源与x86知识全解析

本文详细介绍了编程学习中多个领域的优秀书籍和博客资源,涵盖逆向工程、C/C++、x86/x86-64架构、ARM、汇编语言、Java、UNIX、密码学等多个方向。同时,深入解析了x86架构的核心知识,包括术语、通用寄存器、FPU寄存器、SIMD寄存器、调试寄存器以及常用指令的使用方法和操作步骤。通过本文,读者可以系统地掌握底层编程知识,并应用于逆向工程、系统开发和性能优化等领域。

tree的博客 219

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

研究生复试上机基本题型及思路总结(图论算法专题)

研究生复试上机基本题型及思路总结(图论算法专题)一、 并查集1.1 基本原理1.2 操作方法1.3 解决问题二、最小生成树2.1 基本原理2.2 操作方法2.3 解决问题三、最短路径四、拓扑排序五、关键路径 一、 并查集 1.1 基本原理 并查集用于处理一些不交集的合并和查询问题,有两个主要的功能,一是判断任意的两个元素是否处在同一个集合,二是按照要求合并不同的集合。 1.2 操作方法 并查集的基...

国家熬夜运动比赛中心 1054

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

图论专题(二十一):并查集的“工程应用”——拔线重连,修复「连通网络」

今天这道题,让我们看到了图论中**“数量关系”**的美妙。冗余边:在一个已经连通的分量内部再加边,就是冗余(这就形成了环)。连通代价:要把k个分量连通,必须且只需k-1条边。只要我们手中的总边数(资源)大于等于总节点数-1(需求),我们就拥有了足够的“冗余边”去填补所有的“连通代价”。并查集在这里,不仅帮我们维护了连通性,通过维护count变量,它还直接告诉了我们当前的“分裂程度”。下一篇,我们将利用并查集处理一种更有趣的逻辑关系——“等式方程的可满足性”。当==和!

2301_80334067的博客 1189

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

并查集算法总结&专题训练

1.概述 并查集是一种数据结构,用于图论之中(更多时候用于树),通常用来维护一张无向图内 O(1)O(1)O(1) 判断两个点是否在同一个连通块内,有很多的用法,扩展性也比较高。 2.例题 下面还是通过一道例题讲解并查集的用法。 link 我们假设这 4 个元素分别表示 4 个人。假设每个人都会在一个群内,第 iii 个人的群主表示为 faifa_ifai​ (其实如果抽象成一棵树,就是 iii 的父亲节点) 初始时,每一个人单独在一个群内,则令 fai=ifa_i=ifai​=i (这一步是并查集的初始化

Plozia 的小窝 506

图论专题总结

ACM课程的最后一个专题,图论,其实这个专题还是比较有意思的,不过因为最后课时紧张,讲的也不是很详细。对于图也只是学个皮毛,因为快到期末考试了,题目做的也不是很多,其实还是学的东西不深,后面题目一难就不会做了。

Bourbon 1358

图论专题整理[主攻洛谷

洛谷例题【p2661 信息传递 大佬思路:并查集 附上题解【来自洛谷用户 【bie淖_kkk&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;anyway】 并查集求最小环 把每个同学看成一个点,信息的传递就是在他们之间连有向边,游戏轮数就是求最小环。 图论求最小环,我在里面看到了并查集。 假如说信息由A传递给B,那么就连一条由A指向B的边,同时更新A的父节点,A到它的父节点的路径长也就是B到它的父节点

qq_43337366的博客 824
上一篇: 题解-摆花
下一篇: 题解-铺瓷砖
Cancelleds
博客等级 码龄8年 1110粉丝 166原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值