代码随想录Day 55|题目:并查集理论基础、107. 寻找存在的路径

news2024/9/25 9:29:24

提示:DDU,供自己复习使用。欢迎大家前来讨论~

文章目录

  • 图论part05
      • 并查集理论基础
      • 背景和用途
      • 原理和操作
      • 路径压缩
      • 按秩合并
      • 代码模板
      • 常见误区
      • 复杂度分析
      • 总结
      • 解题步骤
      • 为什么使用并查集
    • 107. 寻找存在的路径
      • 1. 解题步骤
      • 2. 并查集具体操作
      • 3. C++代码实现
    • 总结

图论part05

并查集理论基础

并查集是一种数据结构,用于处理一些不交集的合并及查询问题。以下是并查集理论基础的重点内容:

背景和用途

  • 并查集主要用于解决连通性问题,即判断两个元素是否在同一个集合里。
  • 它包含两个基本功能:
    1. 合并操作:将两个元素添加到同一个集合中。
    2. 查找操作:判断两个元素是否在同一个集合中。

原理和操作

  • 初始化:每个元素初始时自己的父节点是自身,表示每个元素自成一个集合。
  • 查找(Find):通过递归查找一个元素的根节点,可以使用路径压缩优化。
  • 合并(Union):将两个元素的根节点进行合并,通常将一个根节点指向另一个。

路径压缩

  • 定义:在查找过程中,将查找到的非根节点直接连接到根节点,减少未来的查找深度。
  • 效果:使得后续的查找操作更快。

按秩合并

  • 定义:在合并两个集合时,较小的树合并到较大的树中,以保持树尽可能扁平。
  • 目的:优化最终合并成的树的高度,减少查找操作的时间复杂度。

代码模板

  • 提供了初始化、查找、合并和判断两个元素是否在同一个集合的函数。
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;
}

常见误区

  • 在合并操作时,必须先查找到各自的根节点再进行合并,而不是直接将两个节点合并。

复杂度分析

  • 空间复杂度:O(n),需要存储每个节点的父节点信息。
  • 时间复杂度:随着操作的增加,时间复杂度趋于O(1)。

总结

  • 并查集是解决特定问题的强大工具,通过路径压缩和按秩合并可以提高其效率。
  • 理解并查集的内部工作原理对于正确使用它至关重要。
  • 通过模拟和实践,可以加深对并查集工作机制的理解。

解题步骤

  1. 初始化并查集:使用init()函数初始化所有节点的父节点。
  2. 处理每条边:对于图中的每条边,使用join(int u, int v)将它们加入到并查集中。
  3. 判断连通性:使用isSame(int u, int v)来判断两个节点是否在同一个集合中。

为什么使用并查集

  • 效率:并查集通过路径压缩和按秩合并优化,使得查找和合并操作非常高效。
  • 简洁:并查集提供了一种简洁的方式来处理图的连通性问题。

C++代码如下:

#include <iostream>
#include <vector>
using namespace std;

int n; // 节点数量
vector<int> father = vector<int> (101, 0); // 按照节点大小定义数组大小

// 并查集初始化
void init() {
    for (int i = 1; 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;
}

int main() {
    int m, s, t, source, destination;
    cin >> n >> m;
    init();
    while (m--) {
        cin >> s >> t;
        join(s, t);
    }
    cin >> source >> destination;
    if (isSame(source, destination)) cout << 1 << endl;
    else cout << 0 << endl;
}

107. 寻找存在的路径

并查集是一种用来处理不交集(没有交集的集合)的合并和查询问题的数据结构。

1. 解题步骤

  • 初始化:把图中的每个点看作是一个独立的岛屿(独立的集合)。
  • 处理每条边:用并查集的技能把两个有连接的点放到同一个集合里。
  • 判断连通性:用并查集来判断起始点和目标点是否在同一个集合里。

2. 并查集具体操作

  • 初始化操作:每个点自成一派,自己认自己是老大。
  • 查找操作:找出一个点的老大(根节点)是谁。
  • 合并操作:把两个点的老大变成同一个人。
  • 判断操作:判断两个点是不是在一个集合里,也就是他们的老大是不是一样。

3. C++代码实现

  • 定义一个数组,数组的每个元素代表一个节点的父节点。
  • 读入节点和边的信息,使用初始化函数让每个节点的父节点指向自己。
  • 读入每条边的信息,用合并函数把两个端点的节点放到同一个集合。
  • 读入起始点和目标点,用判断函数来输出他们是否连通的结果。

C++代码如下:

#include <iostream>
#include <vector>
using namespace std;

int n; // 节点数量
vector<int> father = vector<int> (101, 0); // 按照节点大小定义数组大小

// 并查集初始化
void init() {
    for (int i = 1; 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;
}

int main() {
    int m, s, t, source, destination;
    cin >> n >> m;
    init();
    while (m--) {
        cin >> s >> t;
        join(s, t);
    }
    cin >> source >> destination;
    if (isSame(source, destination)) cout << 1 << endl;
    else cout << 0 << endl;
}

总结

  • 并查集是处理图中节点连通性问题的利器。
  • 通过将图中的边加入到并查集,你可以快速判断任意两个节点是否连通。
  • 路径压缩技巧可以大幅提升并查集的性能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

尚硅谷———-乐(智)尚代驾~~--------Day5----司机认证篇~

前言&#xff1a; Hello亲爱的uu们&#xff0c;在读过了一个愉快的周末后&#xff08;摸鱼了一会&#xff09;&#xff0c;我又回来更新啦&#xff0c;感谢uu们的阅读&#xff0c;话不多说~ 司机认证 当司机点击开始接单的时候&#xff0c;会先判断该司机有没有通过认证&…

关于PCA的一份介绍

在这篇文章中&#xff0c;我将介绍机器学习中的一种无监督学习算法——PCA&#xff0c;因为它主要有两种用途&#xff0c;即降维与特征提取&#xff0c;所以我将将围绕这两种用途来介绍它&#xff0c;包括基本概念&#xff0c;应用与代码实践。 一、 PCA 1.1 概念 PCA&#…

dev containers plugins for vscode构建虚拟开发环境

0. 需求说明 自用笔记本构建一套开发环境&#xff0c;用docker 虚拟插件 dev containers,实现开发环境的构建&#xff0c;我想构建一套LLMs的环境&#xff0c;由于环境配置太多&#xff0c;不想污染本地环境&#xff0c;所以选择隔离技术 1. 环境准备 vscodedocker 2. 步骤…

任意长度并行前缀和 扫描算法 《PMPP》笔记

下面的算法针对于任意长度输入 对于大数据集&#xff0c;首先将输入分为几段&#xff0c;每一段放进共享内存并用一个线程块处理&#xff0c;比如一个线程块使用1024个线程的话&#xff0c;每个块最多能处理2048个元素。 在前面代码中&#xff0c;一个块最后的执行结果保存到了…

桥接模式和NET模式的区别

桥接模式和NET模式的区别 NAT模式&#xff1a; NAT&#xff1a;网络地址转换&#xff08;模式&#xff09;&#xff1a;借助宿主机来上网&#xff0c;没桥接那么麻烦&#xff0c;只用配置DNS即可。 缺点&#xff1a;扎根于宿主机&#xff0c;不能和局域网内其它真实的主机进行…

用Python实现运筹学——Day 2: 线性规划的基本概念

一、学习内容 线性规划的定义&#xff1a; 线性规划&#xff08;Linear Programming, LP&#xff09;是一种用于求解约束条件下线性目标函数最优解的方法。线性规划问题通常涉及最大化或最小化一个线性目标函数&#xff0c;目标函数的变量受一组线性不等式或等式的约束。 目标…

C语言 | Leetcode C语言题解之第435题无重叠区间

题目&#xff1a; 题解&#xff1a; int cmp(int** a, int** b) {return (*a)[1] - (*b)[1]; }int eraseOverlapIntervals(int** intervals, int intervalsSize, int* intervalsColSize) {if (intervalsSize 0) {return 0;}qsort(intervals, intervalsSize, sizeof(int*), cm…

【React】Ant Design 5.x版本drawer抽屉黑边问题

环境 antd: ^5.14.1react: ^18 问题情况 <Drawer open{open} closable{false} mask{false} width{680}getContainer{props.getContainer || undefined}><p>Some contents...</p><p>Some contents...</p><p>Some contents...</p> …

[网络] 网络层--IP协议

目录 一、IP协议 1.1 基本概念 1.2 IP协议报头 1.3 如何将报头和有效载荷分离和分用 1.4 分片与组装 1.5 如何减少分片&#xff1f; 1.6 分片和封装的具体过程 二、网段划分 2.1 再次理解IP地址 2.2 了解DHCP 2.3 网络划分方案 2.4 为什么要进行网络划分 2.5 特殊的…

Java基础——字节流和字符流

字节流和字符流的用法几乎完全一样&#xff0c;区别在于字节流和字符流所操作的数据单元不同&#xff0c;字节流操作的单元是数据单元是8位的字节&#xff0c;字符流操作的是数据单元为16位的字符。 为什么要有字符流&#xff1f; Java中字符是采用Unicode标准&#xff0c;Un…

【Go语言】Go语言结构体全面解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

基于 Canvas 的可缩放拖动网格示例(Vue3以及TypeScript )

文章目录 1. 基本知识2. Vue33. TypeScript 1. 基本知识 基本知识讲解&#xff1a; Canvas API&#xff1a; 一种用于在网页上绘制图形的 HTML 元素&#xff0c;使用 JavaScript 的 Canvas API 来进行绘制 使用 getContext(2d) 方法获取 2D 绘图上下文&#xff0c;允许开发者绘…

MySQL数据库备份详解

文章目录 引言● 数据库备份的重要性 MySQL数据库备份的基础知识● 备份类型1、完全备份2、增量备份3、差异备份 ● 备份工具与方法1、逻辑备份工具——mysqldump2、物理备份工具——Xtrabackup3、第三方解决方案 MySQL数据库备份的实施步骤1、环境准备2、选择合适的备份工具与…

【Linux基础IO】深入解析Linux基础IO缓冲区机制:提升文件操作效率的关键

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;暂无 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux基础IO &#x1f4d2;1. 什么是缓…

14.第二阶段x86游戏实战2-C++语言开发环境搭建-VisualStudio2017

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

基于jsonpath_ng的JSON数据查改增删

jsonpath_ng支持JSON数据的读写操作。 安装 pip install jsonpath-ng测试数据 from jsonpath_ng import parse import jsonjson_data { "store": {"book": [ { "category": "reference","author": "Nigel Rees&qu…

数据集-目标检测系列-鲨鱼检测数据集 shark >> DataBall

数据集-目标检测系列-鲨鱼检测数据集 shark >> DataBall 数据集-目标检测系列-鲨鱼检测数据集 shark 数据量&#xff1a;6k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;百种数据集&#xff0c;持续增加中。 示例&…

【自动驾驶】基于车辆几何模型的横向控制算法 | Stanley 算法详解与编程实现

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

【Python】探索 Elpy:Emacs 中的 Python 开发环境

可以短时间不开心&#xff0c;但别长时间不清醒。 对于使用 Emacs 编辑器的 Python 开发者来说&#xff0c;Elpy 是一个强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它通过整合多个 Emacs Lisp 和 Python 包&#xff0c;提供了一套完整的 Python 编程支持。本文…

丹摩智算平台体验:AI开发从未如此简单

目录 初次接触丹摩智算GPU算力资源表格 轻松创建GPU实例镜像选择 实验过程体验实验中的一些细节 使用后的感受一点小建议总结 最近我一直在学习一些与深度学习相关的知识&#xff0c;准备自己动手做一些模型训练的实验。平时在自己电脑上跑模型总感觉有点吃力&#xff0c;特别是…