当前位置: 首页 > news >正文

图论专题(二十一):并查集的“工程应用”——拔线重连,修复「连通网络」 - 指南

图论专题(二十一):并查集的“工程应用”——拔线重连,修复「连通网络」 - 指南

哈喽各位,我是前端小L。

欢迎来到我们的图论专题第二十一篇!在现实世界的网络工程中,资源往往是有限的。如果我们发现公司里的电脑网络分成了好几个互不相通的局域网,而手头的网线又不够用,该怎么办?

我们必须凭借“拆东墙补西墙”的策略:找到那些“多余”的网线(在一个连通分量内部形成环的线),把它们拔下来,用来连接那些断开的局域网。

这道题的核心在于:如何判断网线“够不够”?以及如果够,大家必须动多少次手?

力扣 1319. 连通网络的处理次数

https://leetcode.cn/problems/number-of-operations-to-make-network-connected/

题目分析:

  • 输入n 台电脑(节点),connections 网线列表(边)。

  • 操作:拔掉一根已有的网线,把它连到另外两台电脑之间。

  • 目标:让所有电脑都连通。求最少操作次数。

  • 特殊情况:如果线缆总数太少,无论怎么移都连不通,返回 -1

核心洞察:“硬性门槛”与“连通数学”

第一道门槛:资源够不够? 图论告诉我们:要连通 n 个节点,至少需要 n - 1 条边(这就构成了一棵生成树)。

  • 如果 connections.size() < n - 1:线缆总数根本不够,神仙难救,直接返回 -1

  • 如果 connections.size() >= n - 1:线缆总数足够!既然总数够,我们一定能通过“拆除冗余、填补空缺”的方式,把图变成连通的。

第二道门槛:需要动几次手? 假设我们用并查集处理完所有的现有连接后,发现网络中还剩下 k互不相通的连通分量(孤岛)。 要把这 k 个孤岛连成一个整体,我们需要搭几座桥? 很简单,把 k 个点串起来,需要 k - 1 条线。

结论:只要总线缆数达标,我们只得计算出当前的连通分量个数 count,答案就是 count - 1。我们不需要关心具体拔哪根线,缘于题目只问“次数”。

算法流程:并查集的标准作业

  1. 硬性检查:如果 connections.size() < n - 1,返回 -1

  2. 初始化并查集

    • parent 数组,大小为 n

    • 关键:初始化连通分量计数器 componentCount = n(一开始大家都是孤岛)。

  3. 遍历连接

    • 对于每一条边 [u, v],调用 union(u, v)

    • union 函数内部:如果 uv 原本不属于同一个集合(rootU != rootV),合并它们,并将 componentCount减 1

  4. 计算结果

    • 遍历结束后,componentCount 就是剩下的连通分量个数。

    • 需要的操作次数 = componentCount - 1

代码完成 (并查集模板应用)

C++

#include 
#include 
using namespace std;
class Solution {
private:// --- 并查集内部类 ---class UnionFind {private:vector parent;int count; // 连通分量个数public:UnionFind(int n) {count = n;parent.resize(n);iota(parent.begin(), parent.end(), 0); // 初始化 0, 1, 2...}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) {parent[rootX] = rootY;count--; // 每次成功合并,孤岛少一个}}int getCount() const {return count;}};
public:int makeConnected(int n, vector>& connections) {// 1. 硬性门槛检查:线缆总数是否足够if (connections.size() < n - 1) {return -1;}// 2. 初始化并查集UnionFind uf(n);// 3. 建立现有的连接for (const auto& conn : connections) {uf.unite(conn[0], conn[1]);}// 4. 计算需要的操作数// 剩下的连通分量个数 - 1,就是连接它们所需的边数return uf.getCount() - 1;}
};

深度复杂度分析

  • V (Vertices):电脑数 n

  • E (Edges):线缆数 connections.size()

  • 时间复杂度 O(n + E * α(n))

    • 初始化并查集得 O(n)。

    • 遍历 E 条边进行合并,每次操作近似 O(1)(阿克曼反函数)。

    • 总时间近似线性。

  • 空间复杂度 O(n)

    • 并查集的 parent 数组。

总结:冗余与连通的辩证关系

今天这道题,让我们看到了图论中**“数量关系”**的美妙。

  • 冗余边:在一个已经连通的分量内部再加边,就是冗余(这就形成了环)。

  • 连通代价:要把 k 个分量连通,必须且只需 k-1 条边。

只要我们手中的总边数(资源)大于等于总节点数-1(需求),我们就拥有了足够的“冗余边”去填补所有的“连通代价”。并查集在这里,不仅帮我们维护了连通性,通过维护 count 变量,它还直接告诉了我们当前的“分裂程度”。

下一篇,我们将利用并查集处理一种更有趣的逻辑关系——“等式方程的可满足性”。当 ==!= 混杂在一起时,我们该如何判断逻辑是否冲突?

下期见!

http://www.jsqmd.com/news/334332/

相关文章:

  • 大模型开源+免费教程,推荐一波大模型图文教程、视频课程(附文档)
  • 必看!零代码实现RAG:Cherry Studio构建私有知识库教程,建议收藏
  • 国产CAD让设计到加工的数据不再“掉链子”
  • Postman
  • 《P3810 【模板】三维偏序 / 陌上花开》
  • AI方向的就业机会将集中在哪些岗位?春招应届生如何提前筹备?
  • 2026年 复印机打印机综合服务推荐榜:租赁销售维修批发一站式解决方案,专业设备与高效服务口碑之选 - 品牌企业推荐师(官方)
  • 申报国自然,如何打破信息差?
  • Avalonia MVVM
  • 基于Kubernetes的AI多租户系统部署实战
  • LazyLLM教程 | 第4讲:RAG项目工程化入门:从脚本走向模块化与可维护性
  • AI Agent规划能力实战:点餐支付售后多任务协同实现,面试官看了都点头!建议收藏
  • 毕业论文盲审在即,现在还没动笔?
  • LLM教程 | 第2讲:10分钟上手一个最小可用RAG系统
  • VLA Notes - kirin
  • 【笔记】【图】
  • 通过 C# 设置 Word 文档背景颜色、背景图
  • 通用 Agent 执行沙箱环境技术方案调研报告
  • LLM教程 | 第1讲:RAG原理解读:让检索增强生成不再是黑盒
  • 2026年圆形、防水与密封连接器厂家三维测评与选型指南 - 品致汇
  • 小白从零开始勇闯人工智能:计算机视觉初级篇(OpenCV补充(1))
  • 【SRC】抓包环境搭建与并发漏洞实战全解
  • 雷鸟创新背着10亿闯三关
  • Java开发者必看!40篇系统教程+完整代码,从入门到精通掌握AI应用开发(建议收藏)
  • PingApi接口开发平台4.0发布
  • 提示工程架构师:用Git思维做提示版控,效率直接拉满
  • 物流无人机承重模块详解
  • 揭秘ACPs/AIP的中心化架构:不是落后而是高效,附智能体跨域协作三种实现方式 | 技术必藏
  • Active Directory 端口列表
  • 玩手机看手机打电话检测数据集VOC+YOLO格式2332张2类别