並查集及其應用

2021-05-02 06:30:22 字數 1482 閱讀 8206

並查集:(union-find sets)是一種簡單的用途廣泛的集合. 並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數、最小公共祖先、帶限制的作業排序,還有最完美的應用:實現kruskar演算法求最小生成樹。其實,這一部分《演算法導論》講的很精煉。

一般採取樹形結構來儲存並查集,在合併操作時可以利用樹的節點數(加權規則)或者利用乙個rank陣列來儲存集合的深度下界--啟發式函式,在查詢操作時進行路徑壓縮使後續的查詢操作加速。這樣優化實現的並查集,空間複雜度為o(n),建立乙個集合的時間複雜度為o(1),n次合併m查詢的時間複雜度為o(m alpha(n)),這裡alpha是ackerman函式的某個反函式,在很大的範圍內這個函式的值可以看成是不大於4的,所以並查集的操作可以看作是線性的。

它支援以下三種操作:

-union (root1, root2) //合併操作;把子集合root2和子集合root1合併.要求:root1和 root2互不相交,否則不執行操作.

-find (x) //搜尋操作;搜尋元素x所在的集合,並返回該集合的名字--根節點.

-ufsets (s) //建構函式。將並查集中s個元素初始化為s個只有乙個單元素的子集合.

-對於並查集來說,每個集合用一棵樹表示。

-集合中每個元素的元素名分別存放在樹的結點中,此外,樹的每乙個結點還有乙個指向其雙親結點的指標。  

-為簡化討論,忽略實際的集合名,僅用表示集合的樹的根來標識集合。

以下給出我的兩種實現:

//abstract: ufset

//author:lifeng wang

(fandywang)

// model one

與model 2 路徑壓縮方式不同,合併標準不同

const

int maxsize = 500010;

intrank[maxsize];

// 節點高度的上界

intparent[maxsize];

// 根節點

intfindset(int x)

void

union(int root1, int root2) }

void

initi(void)

// model two

const

int maxsize = 30001;

intpre[maxsize]; //

根節點i,pre[i] = -num,其中num是該樹的節點數目; //

非根節點j,pre[j] = k,其中k是j的父節點

intfind(int x)

return x; }

void

union(int r1, int r2)

else }

void

initi(void)

並查集及其應用

並查集 union find sets 是一種簡單的用途廣泛的集合.並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數 最小公共祖先 帶限制的作業排序,還有最完美的應用 實現kruskar演算法求最小生成樹。其實,這一部分 演算法導論 講的很精...

並查集及其應用

並查集的學習告一段落,整理總結一下與大家共勉 並查集 union find sets 是一種簡單的用途廣泛的集合.並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數 最小公共祖先 帶限制的作業排序,還有最完美的應用 實現kruskar演算法求最...

模版 並查集(及其加權)

並查集是經典的圖論演算法,用來維護點與集合的關係,也簡潔明瞭。給定 n nn 個點,有 m mm 次操作,每次操作輸入 pppa aab bb 若 p 1 p 1 p 1 則 合併 aaab bb 若 p 2 p 2 p 2 則 查詢 aaab bb 是否同屬乙個集合 並查集初始化 每個父親點 都 ...