【并查集 / 图论】蓝桥云课 - 魔法大陆的城市群(求无向图连通块数量)题解

【并查集 / 图论】蓝桥云课 - 魔法大陆的城市群(求无向图连通块数量)题解

1. 题目概述

  • 题目大意 :给定 nnn 个城市和 mmm 条双向道路。如果两个城市之间可以通过道路直接或间接到达,则属于同一个"城市群"。求魔法大陆上一共有多少个城市群(即求无向图中的连通块数量)。
  • 数据规模 :2≤n≤1052 \le n \le 10^52≤n≤105,1≤m≤2×1051 \le m \le 2 \times 10^51≤m≤2×105

2. 解题思路

本题是经典的无向图连通块计数问题 。由于数据规模 nnn 达到了 10510^5105,使用 并查集(Disjoint Set Union, DSU) 是最简洁且高效的解法。

  1. 核心思想

    • 初始时,将 nnn 个城市视为 nnn 个互相独立的城市群,设置答案计数器 ans = n
    • 顺序读入每条双向道路 (u,v)(u, v)(u,v),利用并查集查找 uuu 和 vvv 的根节点:
      • 若根节点不同,说明这两个城市群之前不连通,通过当前道路合并两个集合,并将 ans 减 1。
      • 若根节点相同,说明它们早已连通,忽略该条边。
    • 处理完所有道路后,剩余的 ans 即为最终的城市群数量。
  2. 为什么选择并查集而非 DFS

    • 无需显式建图:不需要构造邻接表保存边关系,边读入边处理,节省内存。
    • 防爆栈 :数据规模 n=105n=10^5n=105 时,若图退化为一条长链,DFS 递归层数过深易引发栈溢出(Segmentation Fault)。并查集配合路径压缩则非常稳定。

3. C++ 源码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 100005;
int parent[MAXN];

// 查找根节点(带路径压缩)
int find(int x) {
    if (parent[x] == x) return x;
    return parent[x] = find(parent[x]); // 路径压缩,扁平化树结构
}

int main() {
    // 优化标准输入输出流
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    if (!(cin >> n >> m)) return 0;

    // 1. 初始化:每个城市各自独立为一个集合
    for (int i = 1; i <= n; i++) {
        parent[i] = i;
    }

    int ans = n; // 初始连通块数量为 n

    // 2. 依次处理每条边
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        int rootU = find(u);
        int rootV = find(v);

        // 不属于同一连通块则进行合并,连通块总数 -1
        if (rootU != rootV) {
            parent[rootU] = rootV;
            ans--;
        }
    }

    // 3. 输出最终的连通块数量
    cout << ans << "\n";

    return 0;
}

4. 复杂度分析

  • 时间复杂度 :O(n+m⋅α(n))O(n + m \cdot \alpha(n))O(n+m⋅α(n))。其中 α\alphaα 为阿克曼函数的反函数,近乎于常数 O(1)O(1)O(1)。即使在最坏情况下,总运算次数也在 10510^5105 级别,运行时间不超过 20ms。
  • 空间复杂度 :O(n)O(n)O(n)。仅需开辟一个大小为 10510^5105 的 parent 父节点数组,内存消耗小于 1MB。
相关推荐
aqiu11111114 小时前
【LeetCode 902】最大为 N 的数字组合 - 详细题解与数位组合思路
数据结构·算法·leetcode·蓝桥杯·数位dp
Chester_19992 天前
CSP202312C.树上搜索
开发语言·数据结构·c++·蓝桥杯·stl
CoderYanger3 天前
A.每日一题:3622. 判断整除性
java·程序人生·算法·leetcode·面试·职场和发展·蓝桥杯
Chester_19995 天前
CSP202303C.LDAP
开发语言·c++·蓝桥杯·stl
lvwangshu5 天前
P6534 [COCI 2015/2016 #1] UZASTOPNI 等差树列 题解
动态规划·图论·题解·性质题
positive_zpc8 天前
进阶数据结构图——关键路径(四)
数据结构·图论·关键路径
Chester_19998 天前
CSP202206C.角色授权
开发语言·数据结构·c++·蓝桥杯
Chester_19999 天前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
云淡风轻~窗明几净9 天前
宇宙管理学猜想
算法·图论