C++并查集:高效解决连通性问题

一、前言

C++ 语法、面向对象、STL 已经全部收官。从今天开始,正式进入高阶数据结构与算法深耕 。首篇先学并查集:结构简单、代码短、考点极多、适用场景非常广。

二、并查集是什么

并查集(Disjoint Set Union,DSU)三个核心操作:

  1. 合并:把两个集合合并成一个
  2. 查找:找某个元素的根节点
  3. 判连通:判断两个元素是否在同一个集合

形象理解:每个人是一个节点,认识的人归为一个圈子 ,并查集就是用来管理圈子、合并圈子、查是否同圈

三、并查集核心思想

  • 每个节点有一个父节点 parent \[\]
  • 根节点:自己的父节点是自己
  • 找祖先:一路往上找,直到父节点等于自身
  • 合并集合:把一个集合的根,挂到另一个集合根下面

四、基础朴素版并查集

1. 初始化

每个人初始自己是一个集合,父节点等于自己

复制代码
const int N = 1005;
int parent[N];

// 初始化
void init(int n)
{
    for(int i = 1; i <= n; i++)
    {
        parent[i] = i;
    }
}

2. 查找根节点

复制代码
int find(int x)
{
    if(parent[x] == x) 
        return x;
    return find(parent[x]);
}

3. 合并两个集合

复制代码
void unite(int x, int y)
{
    int fx = find(x);
    int fy = find(y);
    if(fx != fy)
    {
        parent[fy] = fx;
    }
}

4. 判断是否连通

复制代码
bool isSame(int x, int y)
{
    return find(x) == find(y);
}

五、优化一:路径压缩(必加)

朴素版查找层数多、效率低。路径压缩:查找时把沿途所有节点直接挂到根节点,下次查找 O (1)。

优化后 find 函数:

复制代码
int find(int x)
{
    if(parent[x] == x)
        return x;
    // 路径压缩:递归回溯直接指向根
    parent[x] = find(parent[x]);
    return parent[x];
}

刷题默认必写路径压缩

六、优化二:按秩合并(可选)

维护树的高度 / 节点数量,合并时小树挂大树 ,防止树过高。日常刷题只写路径压缩就够用,竞赛再加上按秩合并。

七、并查集完整万能模板(可直接复制刷题)

复制代码
#include <iostream>
using namespace std;

const int N = 1005;
int parent[N];

// 初始化
void init(int n)
{
    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)
{
    x = find(x);
    y = find(y);
    if(x != y)
        parent[y] = x;
}

// 判断同集合
bool same(int x, int y)
{
    return find(x) == find(y);
}

int main()
{
    int n,m;
    cin >> n >> m;
    init(n);

    while(m--)
    {
        int op,x,y;
        cin >> op >> x >> y;
        if(op == 1)
            unite(x,y);
        else
        {
            if(same(x,y)) cout << "Yes\n";
            else cout << "No\n";
        }
    }
    return 0;
}

八、经典适用场景

  1. 判断图中两点是否连通
  2. 朋友圈、亲戚关系合并
  3. 最小生成树 Kruskal 算法必备
  4. 岛屿数量、连通块统计
  5. 区间合并、分组问题

九、今日核心总结

  1. 并查集三大操作:初始化、查找、合并
  2. 路径压缩是标配优化,极大提升效率
  3. 模板固定,刷题直接套用即可
  4. 常用于连通性判断、集合合并、图论基础题

十、课后练习

  1. 手写并查集模板,实现 5 个元素合并、判断连通
  2. 输入多组关系,统计最终有多少个独立连通块
相关推荐
用户37215742613540 分钟前
Java 设置 Word 文档编辑限制并允许指定区域编辑
java
船厂电气自动化ai大模型1 小时前
AI大模型与数学·第57课 傅里叶全套工具链综合实战:串联级数/连续变换/DFT/FFT,图像、音频、扩散模型完整例题
数据结构·人工智能·深度学习·算法·机器学习
宠友信息1 小时前
社区类源码开发实践中的仿小红书系统技术要点分析
java·spring boot·redis·mysql·uni-app·vue·内容运营
用户3721574261351 小时前
Java 设置 PDF 表单域只读或扁平化
java
人工智能培训2 小时前
人工智能数据安全下的个人信息保护实践方案
大数据·人工智能·算法·生活
元启数宇2 小时前
幕墙AI设计算法逻辑:元启数宇如何智能分格
人工智能·算法
luteres2 小时前
Spring学习笔记
java·后端·spring
宵时待雨3 小时前
优选算法专题16:多源BFS
算法·宽度优先
南城以南溫暖如初1473 小时前
从零搭建24小时自助健身系统:技术选型与核心模块实战
java·spring boot·redis·mysql·vue·mybatis
重生之后端学习3 小时前
53. 最大子数组和[中等]✅
java·数据结构·算法·leetcode·职场和发展