博客
关于我
算法笔记----好朋友(并查集问题)
阅读量:567 次
发布时间:2019-03-09

本文共 2054 字,大约阅读时间需要 6 分钟。

并查集(Union-Find)是一种高效的数据结构,广泛应用于处理动态的连通性问题。以下是优化过的技术文档,基于用户的要求已进行适当修改,确保内容具有专业性和可读性。

并查集优化解法

问题分析

我们需要处理多组朋友关系,并找到每组的根节点数目。同一个集合的所有节点应共享一个根节点,最终统计这些根节点的数量即可。

核心思想

  • 并查集:维护每个节点的父节点,以及一个标记数组记录是否为根节点。
  • 路径压缩:在查找根节点时,压缩路径,使后续查找更高效。
  • 合并操作:将不同集合中的节点合并到一起。
  • 优化方案

    路径压缩

    在查找根节点时,将当前节点的父节点指向其祖父。这样做可以减少查找时间,因为每次查找时路径会被缩短。

    工作流程

  • 初始化:每个节点的父节点指向自己,标记其是否为根节点。
  • 处理输入:逐个处理朋友关系,执行合并操作。
  • 统计集合数:遍历所有节点,统计根节点数量。
  • 技术细节

    findFather函数

    int findFather(int x) {    if (father[x] != x) {        father[x] = findFather(father[x]);    }    return father[x];}
    • 递归查找:递归地查找节点的祖父,直到找到根节点。
    • 路径压缩:将当前节点的父节点指向根节点,减少后续查找的路径长度。

    Union函数

    void Union(int a, int b) {    int fa = findFather(a);    int fb = findFather(b);        if (fa != fb) {        father[fa] = fb;    }}
    • 合并操作:找到两节点的根节点,如果不同,则将一棵树合并到另一棵树的根节点下。
    • 无需额外结构:仅需修改父节点即可高效地管理集合。

    初始化函数

    void init(int n) {    for (int i = 1; i <= n; ++i) {        father[i] = i;    }}
    • 初始化父节点:每个节点的父节点初始化为自身,标记为非根节点。

    样例分析

    • 输入样例:7 51 22 33 11 45 6
    • 处理过程:逐个处理每对朋友关系,合并相应的集合。
    • 结果:最终有3个独立的集合。

    代码实现

    #include 
    #include
    #include
    #include
    #include
    using namespace std;const int maxn = 101;int father[maxn];int isRoot[maxn]; // 是否为根节点标记int findFather(int x) { if (father[x] != x) { father[x] = findFather(father[x]); } return father[x];}void Union(int a, int b) { int fa = findFather(a); int fb = findFather(b); if (fa != fb) { father[fa] = fb; }}void init(int n) { for (int i = 1; i <= n; ++i) { father[i] = i; isRoot[i] = false; }}int main() { cin >> n >> m; init(n); for (int i = 0; i < m; ++i) { int a, b; cin >> a >> b; Union(a, b); } for (int i = 1; i <= n; ++i) { isRoot[findFather(i)] = true; } int ans = 0; for (int i = 1; i <= n; ++i) { if (isRoot[i]) { ans++; } } cout << ans << endl; return 0;}

    优化效果

  • 路径压缩:通过将路径直接连接到根节点,减少查找时间。
  • 总体复杂度:时间复杂度接近O(α(n)),α为阿克曼函数,增长极慢。
  • 空间复杂度:O(n),适合处理大规模数据。
  • 通过这段优化代码,可以高效地解决类似问题,找到每个集合的根节点数目。该方案适用于动态数据的连通性问题,是数据结构和算法学习中的基础内容。

    转载地址:http://ndapz.baihongyu.com/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | 基于深度学习的轮胎缺陷检测系统
    查看>>
    OpenCV与AI深度学习 | 如何在 Docker 容器中使用 GPU
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV传统方法实现密集圆形分割与计数(详细步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV实现扫描文本矫正应用与实现详解(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用YOLOv8 Pose实现瑜伽姿势识别
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用YoloV8实例分割识别猪的姿态(含数据集)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用姿态估计算法构建简单的健身训练辅助应用程序
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YoloV5和Mask RCNN实现汽车表面划痕检测(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YOLOv9+SAM实现动态目标检测和分割(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YOLOv9和OpenCV实现车辆跟踪计数(步骤 + 源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 文本图片去水印--同时保持文本原始色彩(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战—使用YOLOv8图像分割实现路面坑洞检测(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战篇——基于YOLOv8和OpenCV实现车速检测(详细步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战|OpenCV实时弯道检测(详细步骤+源码)
    查看>>
    OpenCV与AI深度学习 | 实践教程|旋转目标检测模型-TensorRT 部署(C++)
    查看>>
    OpenCV与AI深度学习 | 工业缺陷检测中数据标注需要注意的几个事项
    查看>>
    OpenCV与AI深度学习 | 干货 | 深度学习模型训练和部署的基本步骤
    查看>>
    OpenCV与AI深度学习 | 手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤 + 源码)
    查看>>
    OpenCV与AI深度学习 | 深度学习检测小目标常用方法
    查看>>
    OpenCV与AI深度学习 | 超越YOLOv10/11、RT-DETRv2/3!中科大D-FINE重新定义边界框回归任务
    查看>>