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

算法训练营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.xdnf.cn/news/18400.html

相关文章:

  • 信号和共享内存
  • Linux------《零基础到联网:CentOS 7 在 VMware Workstation 中的全流程安装与 NAT 网络配置实战》
  • Visual Studio 2022+OpenCV-Python安装及配置方法
  • 涡流-信号完整性分析
  • pytest高级用法之插件开发
  • 1A AMOLED显示屏电源芯片BCT1838
  • 01-Docker-简介、安装与使用
  • Day09 Go语言深入学习(1)
  • 进程与线程
  • langchain的简单应用案例---(1)使用langchain构建本地知识库
  • K近邻算法(knn)
  • 基于 RxJava 构建强大的 Android 文件下载管理器
  • Android SystemServer 中 Service 的创建和启动方式
  • AI与大数据驱动下的食堂采购系统源码:供应链管理平台的未来发展
  • Git#cherry-pick
  • QT示例 基于Subdiv2D的Voronoi图实现鼠标点击屏幕碎裂掉落特效
  • Day22 顺序表与链表的实现及应用(含字典功能与操作对比)
  • 服务器无公网ip如何对外提供服务?本地网络只有内网IP,如何能被外网访问?
  • Vue.prototype 的作用
  • JUC之CompletableFuture【中】
  • Redis Reactor 模型详解【基本架构、事件循环机制、结合源码详细追踪读写请求从客户端连接到命令执行的完整流程】
  • FPGA 在情绪识别领域的护理应用(一)
  • 论文阅读系列(一)Qwen-Image Technical Report
  • 中和农信如何打通农业科技普惠“最后一百米”
  • 企业架构是什么?解读
  • 通过分布式系统的视角看Kafka
  • python黑盒包装
  • Matplotlib数据可视化实战:Matplotlib图表注释与美化入门
  • 抓取手机游戏相关数据
  • LWIP流程全解