並查集初步

2021-09-23 18:06:44 字數 2469 閱讀 1205

有若干節點,並將其中一些節點對進行連線,要判斷任意兩個節點是否連通(有路徑到達,而不要求直接連線),連通後就不會斷開連通關係,此時就可以使用並查集。並查集擅長動態維護許多具有傳遞性的關係,能在無向圖中維護節點之間的連通性。

要判斷兩個節點是否連通,可以把連通的節點加入到各自的集合裡,也就是,同乙個集合裡的節點都是連通的,不同集合裡的節點是不連通的。

如圖,節點a、b、c、d屬於同乙個集合,它們之間是連通的;節點x、y、z屬於同乙個集合,它們之間也是連通的。但是,不同集合裡的節點,如b和x,是不連通的。

可以發現,每個集合構成了樹形的結構,同乙個集合裡的節點,它們的根節點是相同的。要判斷兩個節點是否連通,只需要判斷它們的根節點是否一致即可。

並查集的api定義:

classuf;

// 連線節點p和q

void

join

(int x,

int y)

;// 判斷兩個節點是否連通

bool

isconnected

(int x,

int y);}

;

並查集的儲存結構可以使用陣列或鍊錶,一般採用陣列作為實現的方式。陣列記錄元素的父節點。例如,a[i] = j,表示節點i的父節點是節點j。

初始時,每個節點各自作為乙個集合,也就是節點的父節點是自身。

private

: vector<

int> parent;

public:uf

(int n)

}

查詢節點的根節點時,如果節點的父節點是自身,那麼該節點就是根節點。否則,順著父節點不斷向上找,直至根節點。

int

find

(int x)

連線兩個節點時,實際上就是把兩個節點的所在的集合合併成乙個。首先需要找到兩個節點的根節點,把其中乙個根節點的父節點修改為另乙個根節點。

void

join

(int x,

int y)

對於 find 的過程,可以修改節點的父節點來加速下次查詢,這個優化稱為「路徑壓縮」。

例如,在查詢根節點的過程中,修改沿途節點的父節點為根節點:

非遞迴的寫法:

int

find

(int x)

int tmp;

while

(x != root)

return x;

}

還有其它的路徑壓縮方式。例如,在查詢根節點的過程中,若節點不是根節點,就將節點的父節點修改為爺節點(父節點的父節點):

}對於 join 的過程,如果不加任何策略合併,可能會形成很長的路徑,應該盡量選擇深度更小的集合的根節點進行父節點的修改。

集合的秩,也就是集合所對應的樹的深度。

如果兩個集合的秩不相等,就把秩小的集合的根節點的父節點修改為秩大的集合的根節點。如果兩個集合的秩相等,那麼,將其中乙個集合的根節點的父節點修改為另乙個集合的根節點,同時,將未修改父節點的根節點的集合的秩+1。

classuf}

void

join

(int x,

int y)

else}}

}...

也可以在根節點儲存秩的資訊,思路參考下面的「按size合併」

為了記錄集合的size,也就是集合包含節點的個數,可以將根節點的父節點的值修改為「-1*集合包含節點的個數」,同時,根節點的判斷方式修改為父節點的值小於0。合併時,將節點數少的集合併入節點數多的集合,也就是修改節點數少的集合的根節點的父節點為節點數多的集合的根節點。注意,在修改父節點前要更新節點數多的集合的節點數。

classuf}

intfind

(int x)

void

join

(int x,

int y)

else}}...

不過,按size合併的策略並不總能選擇深度更小的集合的根節點進行父節點的修改,例如本文第乙個圖的情況。

並查集初步

對資料進行合併,查詢某個資料的祖先,建立資料間的聯絡。int fathe mx 根節點 int rank x 樹的高度 void ini intfind int x intunite int x,int y 1 wireless network 題意 有n臺電腦,電腦的覆蓋範圍為k公尺,在覆蓋範圍內...

並查集初步

並查集可以動態維護若干個不重疊的集合,支援查詢和合併兩個操作,在實際應用中比較廣泛。並查集的主要功能是查詢元素的集合歸屬,同時支援集合的合併操作。並查集的實現方法 對於每個集合,選擇乙個元素作為其代表元素,而若兩個元素所在集合的代表元素相同,則說明它們在同乙個集合中。具體如何實現呢?有一種思路,可以...

並查集的初步學習

一 並查集是什麼 並查集是對一堆具有相互關聯的資料中快速找出兩個物件是否具有關聯關係的資料集合,這個問題看似簡單實際上牽扯到大量的計算。二 並查集的解決思路 a 先初始化乙個陣列,然後再讓這個陣列的內容指向本身。b 若這個陣列某個下標與某個下標具有關聯性,那麼就講某個下標的內容指向另乙個下標。解決這...