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

UVA 10608 Friends:並查集求最大朋友圈規模

     編輯:C++ 入門

問題描述

N 個人,M 對認識關係(無向邊)。朋友圈定義為連通分量。求最大朋友圈的人數。多測試用例,N ≤ 30000, M ≤ 500000。

並查集(Disjoint Set Union)

維護每個集合的代表元與大小:

  • parent[x]:父節點,根節點 parent[x] == x
  • size[x]:以 x 為根的集合大小(僅根節點有效)

核心操作


int find(int x) {
    return parent[x] == x ? x : parent[x] = find(parent[x]); // 路徑壓縮
}
void unite(int a, int b) {
    a = find(a); b = find(b);
    if (a == b) return;
    if (size[a] < size[b]) swap(a, b); // 按秩合併
    parent[b] = a;
    size[a] += size[b];
}

算法流程

  1. 初始化:parent[i]=i, size[i]=1
  2. 讀入 M 條邊,調用 unite(x, y)
  3. 遍歷 1..N,找根節點 find(i)==i,取最大 size[i]

完整代碼


#include 
#include 
using namespace std;
const int MAXN = 30005;
int parent[MAXN], sz[MAXN];

int find(int x) { return parent[x]==x ? x : parent[x]=find(parent[x]); }

int main() {
    int T; scanf("%d", &T);
    while (T--) {
        int N, M; scanf("%d%d", &N, &M);
        for (int i=1; i<=N; ++i) parent[i]=i, sz[i]=1;
        for (int i=0; i

複雜度

  • 時間:O((N+M) α(N)) ≈ 線性,α 為反阿克曼函數
  • 空間:O(N)

關鍵優化

  • 路徑壓縮:find 時將路徑上所有節點直接指向根
  • 按秩/按大小合併:小樹掛大樹,保證樹高 O(log N)
  • 兩者結合使時間複雜度趨近常數
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved