当前位置: 首页 > news >正文

算法训练营day55 图论⑤ 并查集理论基础、107. 寻找存在的路径

        本篇博客介绍并查集这种数据结构组织方法,以及适合解决的问题,理解并查集的很好的方法是跟着博客链接中的模拟步骤推导一遍

并查集理论基础

        并查集常用来解决连通性问题。大白话就是当我们需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集。

        并查集主要有两个功能:

  • 将两个元素添加到一个集合中。
  • 判断两个元素在不在同一个集合

        原理:通过数据结构(数组)连接同一集合元素

        路径压缩:将非根节点的所有节点直接指向根节点。

代码模板

        通过模板,我们可以知道,并查集主要有三个功能。注意对于“寻根”的理解

  1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个
  2. 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上
  3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点

并查集模拟过程        

int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
vector<int> father = vector<int> (n, 0); // C++里的一种数组结构// 并查集初始化
void init() {for (int i = 0; i < n; ++i) {father[i] = i;}
}
// 并查集里寻根的过程
int find(int u) {return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩
}// 判断 u 和 v是否找到同一个根
bool isSame(int u, int v) {u = find(u);v = find(v);return u == v;
}// 将v->u 这条边加入并查集
void join(int u, int v) {u = find(u); // 寻找u的根v = find(v); // 寻找v的根if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回father[v] = u;
}

优化思路

        其实还有另一种方法:按秩(rank)合并。rank表示树的高度,即树中结点层次的最大值。但是很显而易见,这种合并方式不如之前的方式平缓,所以增益不是很显著

107. 寻找存在的路径

        并查集主要解决集合问题,即:两个节点在不在一个集合,也可以将两个节点添加到一个集合中

        成体不难,核心在于理解并查集的关键成员函数

class UnionFind:def __init__(self, size):self.parent = list(range(size + 1))  # 初始化并查集
# range(size + 1) 生成一个从 0 到 size 的整数序列(包含 size 本身)
# list(range(size + 1)) 将这个序列转换为列表def find(self, u):if self.parent[u] != u:self.parent[u] = self.find(self.parent[u])  # 路径压缩return self.parent[u]def union(self, u, v):root_u = self.find(u)root_v = self.find(v)if root_u != root_v:self.parent[root_v] = root_udef is_same(self, u, v):return self.find(u) == self.find(v)def main():import sysinput = sys.stdin.readdata = input().split()index = 0n = int(data[index])index += 1m = int(data[index])index += 1uf = UnionFind(n)for _ in range(m):s = int(data[index])index += 1t = int(data[index])index += 1uf.union(s, t)source = int(data[index])index += 1destination = int(data[index])if uf.is_same(source, destination):print(1)else:print(0)if __name__ == "__main__":main()

http://www.lryc.cn/news/625671.html

相关文章:

  • 游戏相机震动与武器后坐力实现指南
  • ReLens「Focus DSLR 大光圈虚化相机」v4.1.2 f 解锁付款版 —一款专业大光圈和单反级背景虚化编辑软件
  • 基于 RxJava 构建强大的 Android 文件下载管理器
  • Linux管道
  • 云原生俱乐部-shell知识点归纳(1)
  • Codeforces 斐波那契立方体
  • DaemonSet控制器
  • 《Java 多线程全面解析:从基础到生产者消费者模型》
  • SpringClound——网关、服务保护和分布式事务
  • 编排之神--Kubernetes中的认证授权详解
  • 无训练神经网络影响下的智能制造
  • 论文阅读:Prompt Optimization in Large Language Models
  • 基于SpringBoot的篮球馆预约管理系统【2026最新】
  • iOS 性能监控实践,如何构建从开发到运维的持续优化体系
  • 基于prompt的生物信息学:多组学分析的新界面
  • 在linux系统中下载Andconda
  • 基于正则的Java的IP地址格式校验(ipv4 ipv6)
  • PythonDay31
  • Kubernetes集群安装部署--flannel
  • 【Langchain系列七】Langchain+FastAPI(字符串输出与OpenAI规范流式输出)+FastGPT
  • openssl生成自签名证书的方法
  • 算法第五十一天:图论part02(第十一章)
  • AI驱动的SEO关键词优化秘籍
  • 【LeetCode题解】LeetCode 162. 寻找峰值
  • SQL 语句进阶实战:从基础查询到性能优化全指南
  • Docker+Nginx+Node.js实战教程:从零搭建高可用的前后端分离项目
  • 黑客哲学之学习笔记系列(六)
  • Node.js完整安装配置指南(包含国内镜像配置)
  • HTB 赛季8靶场 - CodeTwo
  • HarmonyOS 实战:学会在鸿蒙中使用第三方 JavaScript 库(附完整 Demo)