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

並查集總結:路徑壓縮、按秩/按大小合並、應用例題

     編輯:C++ 入門

並查集基本操作

  • makeSet(x):初始化,每個元素自成一集,父指針指向自己。
  • find(x):尋找集合代表元(根),路徑壓縮優化:if (p[x]!=x) p[x]=find(p[x]); return p[x];
  • union(x,y):合併兩集合,找根後掛接。

兩種合並優化策略

1. 按秩合並

維護 rank[x] 近似樹高。合併時將秩小的樹掛到秩大的樹下;秩相等任掛一邊,被掛樹根秩 +1。


int rank[MAXN];
void makeSet(int n) { for(i=0;irank[y]) p[y]=x;
    else { p[x]=y; if(rank[x]==rank[y]) rank[y]++; }
}

應用例:HDU 1325 判斷是否為樹(檢查連通性、無環、入度)。

2. 按大小合並

根節點存儲負的集合大小(p[root] = -size)。合併時將小集合併入大集合,更新大小。


int p[MAXN];
void makeSet(int n) { for(i=0;i

應用例:HDU 1856 最大朋友圈(求最大集合大小)。

非遞歸 find 實現


int find(int x) {
    int root = x;
    while (p[root] >= 0) root = p[root];
    while (x != root) { int tmp = p[x]; p[x] = root; x = tmp; }
    return root;
}

應用場景總結

  • 動態連通性查詢(網絡、社交圖)。
  • Kruskal 最小生成樹(檢測環)。
  • 離線查詢(Tarjan LCA、並查集撤銷)。
  • 集合大小/成員統計(按大小合並天然支持)。
  • 二分圖檢測(帶權並查集/擴展域)。

模板代碼(通用版)


struct DSU {
    vector p, sz;
    DSU(int n=0) { init(n); }
    void init(int n) { p.resize(n); sz.assign(n,1); iota(p.begin(), p.end(), 0); }
    int find(int x) { return p[x]==x?x:p[x]=find(p[x]); }
    bool unite(int a, int b) {
        a=find(a); b=find(b); if(a==b) return false;
        if(sz[a]
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved