城市连通性(200分 / 并查集)

题目描述 :有 n 个城市(编号 1 ~ n)和 m 条双向道路。每条道路连接两个城市。现在要判断:

  1. 这些城市是否全部连通(即任意两个城市之间都有路径)。

  2. 如果全部连通,输出 YES;否则输出需要最少新增多少条道路才能全部连通。

输入:

  • 第一行:n m(1 ≤ n ≤ 10^5,0 ≤ m ≤ 2×10^5)

  • 接下来 m 行:每行两个整数 u v,表示一条道路。

输出:

  • 若已全部连通:YES

  • 否则:一个整数,表示最少新增道路数。

示例:

text

复制代码
输入:
5 3
1 2
2 3
4 5

输出:
1

解释:连通分量为 {1,2,3} 和 {4,5},需要 1 条路连接两个分量。

解题思路

用并查集维护连通分量:

  • 初始每个城市独立,连通分量数 components = n。

  • 每合并两个不同集合,components--。

  • 最终若 components == 1,输出 YES;否则输出 components - 1(最少新增道路数 = 连通分量数 - 1)。

参考代码

c

复制代码
#include <stdio.h>

int parent[100005];
int rank_[100005];

int find(int x) {
    if (parent[x] != x)
        parent[x] = find(parent[x]); // 路径压缩
    return parent[x];
}

int unite(int a, int b) {
    int ra = find(a), rb = find(b);
    if (ra == rb) return 0;
    if (rank_[ra] < rank_[rb]) {
        parent[ra] = rb;
    } else if (rank_[ra] > rank_[rb]) {
        parent[rb] = ra;
    } else {
        parent[rb] = ra;
        rank_[ra]++;
    }
    return 1;
}

int main(void) {
    int n, m;
    scanf("%d %d", &n, &m);

    for (int i = 1; i <= n; i++) {
        parent[i] = i;
        rank_[i] = 0;
    }

    int components = n;
    for (int i = 0; i < m; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        if (unite(u, v)) components--;
    }

    if (components == 1)
        printf("YES\n");
    else
        printf("%d\n", components - 1);

    return 0;
}
相关推荐
国科安芯9 小时前
星上计算的第一道防线:低轨遥感卫星载荷处理链中的AS32S601型抗辐射MCU—— 面向高分辨率成像与在轨智能处理的场景化综述
大数据·网络·人工智能·单片机·算法·低轨卫星·抗辐射
thusloop9 小时前
零门槛接入 GPT-6-astra 与 claude-opus-5-5,三大场景实战指南
python·gpt·算法·agent·claude·codex
瓦瓦gogo9 小时前
学回溯算法时,我先弄明白了怎么“退回来”
算法
Lzg_na9 小时前
堆和堆排序
算法
TK泰妞10 小时前
TikTok 带货视频如何做多语言本地化?从翻译脚本到重做场景的实用方法
算法·音视频
房开民10 小时前
DDPM 完整原理 + 全套公式串联
算法
lunar_coder10 小时前
哈希扩展 -- 位图思想
c++·算法·哈希算法
秋天的怀念_David10 小时前
听故事学语言 · 数据结构篇 · 序章一 算法之问
数据结构·程序人生·算法
LG.YDX10 小时前
基于中心的3D目标检测和探索追踪-笔记
笔记·算法·目标检测
民乐团扒谱机10 小时前
【读论文】音色在微分音程记忆中的作用
人工智能·深度学习·算法