首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

HDU 1232 暢通工程:並查集統計連通分量

     編輯:C++ 入門

問題描述

給定 n 個城鎮、m 條雙向道路。道路連接的兩個城鎮之間可以互通。目標是使任意兩個城鎮間都能互通(不一定直接相連)。求最少還需建設多少條道路。n < 1000,多測試用例,n=0 結束。

解題思路:連通分量計數

現有道路構成若干連通分量。要將 k 個連通分量連成一個整體,最少需要 k-1 條新道路(樹的邊數 = 點數 - 1)。因此問題轉化為:統計無向圖的連通分量個數。

並查集實現

  • 初始化:每個城鎮自成一集 fa[i] = i
  • 合併:對每條路 (a, b),執行 union(a, b)
  • 統計:掃描 1..n,根節點個數即為連通分量數 cnt
  • 答案:cnt - 1

參考代碼(C++)

#include <iostream>
using namespace std;

const int MAXN = 1010;
int fa[MAXN];

void init(int n) { for (int i = 1; i <= n; i++) fa[i] = i; }
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
void unite(int a, int b) {
    int ra = find(a), rb = find(b);
    if (ra != rb) fa[ra] = rb;
}

int main() {
    int n, m;
    while (cin >> n) {
        if (n == 0) break;
        cin >> m;
        init(n);
        for (int i = 0; i < m; i++) {
            int a, b; cin >> a >> b;
            unite(a, b);
        }
        int cnt = 0;
        for (int i = 1; i <= n; i++) if (find(i) == i) cnt++;
        cout << cnt - 1 << endl;
    }
    return 0;
}

複雜度分析

  • 時間:O(m α(n)),α 為反阿克曼函數,近似常數
  • 空間:O(n)
  • 完全滿足 n < 1000, m 無上限

關鍵點

  1. 題目本質是求連通分量數,答案 = 分量數 - 1
  2. 並查集是處理動態連通性的標準工具
  3. 注意輸入可能有重複邊、自環,並查集天然去重
  4. 建議用 scanf 加速輸入
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved