並查集:(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 是否同屬乙個集合 並查集初始化 每個父親點 都 ...