算法知识点———并查集

devtools/2024/9/23 20:04:57/

并查集是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素。并查集支持两种操作:
合并(Union):合并两个元素所属集合(合并对应的树)
查询(Find):查询某个元素所属集合(查询对应的树的根节点),这可以用于判断两个元素是否属于同一集合。

经典用法:利用并查集检测图中是否有环。
初始parent数组可以设置为下标,表示结点的父亲结点是自己。
然后当结点1和结点2有边的时候可以设置结点2的父亲结点是结点1.结点3的父结点是结点4,那么parent[3] = 4
然后如果1和3这条边想合并的时候只需要合并1的父结点和3的父结点即可,也就是1的父结点是4.这样01234都在一个集合里面,也就是说root[0] == root[2] 表示0和2是互通的。
在这里插入图片描述
下面是合并x节点和y节点的过程
第一步find_root函数找到x节点的根结点或者y节点的根结点
第二步uniin函数合并x节点和y节点

在这里插入图片描述
并查集合并的时候容易导致树倾斜,可以采用秩优化;
每次合并都把深度较小的集合合并在深度较大的集合下面 。这种技术被称为按秩合并
路径压缩实际上是在找完根结点之后,在递归回来的时候顺便把路径上元素的父亲指针都指向根结点。
在这里插入图片描述

题目2:
判断ip是否有连通性,其中连通具有传递性;

输入描述:
第一行包含两个整数n和m,表示已知的IP地址数量和连通关系数量。
接下来n行,每行包含一个字符串和一个整数,表示一个IP地址和它的编号。
接下来m行,每行包含两个整数a和b,表示IP地址对应的编号a和b之间有连通关系。
接下来一行包含一个整数q,表示需要判断连通性的IP地址数量。
接下来q行,每行包含两个字符串,表示需要判断连通性的两个 IP地址。
输出描述
对于每个需要判断连通性的IP地址对,如果它们连通,则输出"Yes",否则输出"No"。
示例1
5 3
192.168.0.1 1
192.168.0.2 2
192.168.0.3 3
192.168.0.4 4
192.168.0.5 5
1 2
2 3
4 5
3
192.168.0.1 192.168.0.2
192.168.0.2 192.168.0.3
192.168.0.3 192.168.0.4
输出:
Yes
Yes
No

#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>using namespace std;// 并查集类
class UnionFind {
public:UnionFind(int n) {parent.resize(n + 1);rank.resize(n + 1, 0);for (int i = 1; i <= n; ++i) {parent[i] = i;}}// 查找集合的根节点,路径压缩优化int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]);}return parent[x];}// 合并两个集合,按秩合并优化void unite(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {if (rank[rootX] > rank[rootY]) {parent[rootY] = rootX;}else if (rank[rootX] < rank[rootY]) {parent[rootX] = rootY;}else {parent[rootY] = rootX;rank[rootX]++;}}}private:vector<int> parent; // 父节点数组vector<int> rank;   // 秩数组 记录每个集合的"秩"或"高度"。
};int main() {int n, m;cin >> n >> m;unordered_map<string, int> ipMap; // IP地址到编号的映射string ip;int id;// 输入n个IP地址和对应的编号for (int i = 0; i < n; ++i) {cin >> ip >> id;ipMap[ip] = id;}// 初始化并查集UnionFind uf(n);int a, b;// 输入m个连通关系for (int i = 0; i < m; ++i) {cin >> a >> b;uf.unite(a, b); // 将a和b所属的集合合并}int q;cin >> q;string ip1, ip2;// 对每个查询判断是否连通for (int i = 0; i < q; ++i) {cin >> ip1 >> ip2;if (uf.find(ipMap[ip1]) == uf.find(ipMap[ip2])) {cout << "Yes" << endl;}else {cout << "No" << endl;}}return 0;
}

http://www.ppmy.cn/devtools/116154.html

相关文章

Llama 3.1 技术研究报告-2

3.3 基础设施、扩展性和效率 我们描述了⽀持Llama 3 405B⼤规模预训练的硬件和基础设施&#xff0c;并讨论了⼏项优化措施&#xff0c;这些措施提⾼了训练效率。 3.3.1 训练基础设施 Llama 1和2模型在Meta的AI研究超级集群&#xff08;Lee和Sengupta&#xff0c;2022&#x…

DNS和ICMP

DNS DNS&#xff08;Domain Name System &#xff09; DNS 是一整套从域名映射到 IP 的系统 关于DNS背景 TCP/IP 中使用 IP 地址和端口号来确定网络上的一台主机的一个程序 . 但是 IP 地址不 方便记忆 . 于是人们发明了一种叫主机名的东西 , 是一个字符串 , 并且…

基于SpringBoot的在线点餐系统【附源码】

​基于SpringBoot的高校社团管理系统&#xff08;源码L文说明文档&#xff09; 4 系统设计 4.1 系统概述 网上点餐系统的结构图4-1所示&#xff1a; 图4-1 系统结构 模块包括主界面&#xff0c;首页、个人中心、用户管理、美食店管理、美食分类管理、美食…

QT中的消息机制(事件机制)总结

Qt 中的消息机制&#xff08;事件机制&#xff09;是框架的核心部分之一&#xff0c;它通过事件驱动模型来处理用户交互和系统事件。Qt 的事件处理系统允许对象之间通过发送和接收消息或事件来进行通信&#xff0c;这种机制使得应用程序能以响应式的方式来处理各种输入和输出。…

【有啥问啥】深入浅出马尔可夫链蒙特卡罗(Markov Chain Monte Carlo, MCMC)算法

深入浅出马尔可夫链蒙特卡罗&#xff08;Markov Chain Monte Carlo, MCMC&#xff09;算法 0. 引言 Markov Chain Monte Carlo&#xff08;MCMC&#xff09;是一类用于从复杂分布中采样的强大算法&#xff0c;特别是在难以直接计算分布的情况下。它广泛应用于统计学、机器学习…

python爬虫初体验(一)

文章目录 1. 什么是爬虫&#xff1f;2. 为什么选择 Python&#xff1f;3. 爬虫小案例3.1 安装python3.2 安装依赖3.3 requests请求设置3.4 完整代码 4. 总结 1. 什么是爬虫&#xff1f; 爬虫&#xff08;Web Scraping&#xff09;是一种从网站自动提取数据的技术。简单来说&am…

WPF 自定义路由事件

WPF 自定义路由事件 一、自定义路由事件步骤 ① 注册路由事件    ② 为路由事件添加 CLR 事件包装器    ③ 创建可激发路由事件的方法 二、注册路由事件 EventManager.RegisterRoutedEvent(String, RoutingStrategy, Type, Type)     作用&#xff1a;将新的路由事件…

Pandas_iloc_loc_哪个是inclusive哪个是exclusive

iloc 和 loc 包括不包括结尾写的那个行&#xff08;列&#xff09;&#xff1f; 不一样&#xff01; iloc[istart:iend] exclusive on iend 不包括结尾那行&#xff08;列&#xff09;&#xff01; loc[start:end] inclusive on end 包括结尾那行&#xff08;列&#xff09;&am…