資料結構之並查集

2021-10-06 17:30:42 字數 1570 閱讀 4584

並查集是一種用來管理元素分組情況的資料結構。並查集可以高效地進行如下操作。不過需要注意並查集雖然可以進行合併操作,但是卻無法進行分割操作。

n個城市中(編號1~n),有一些城市間會有無向的通路。

現在小明想從a城市到b城市,判斷是否能實現?即a和b是否有直接或間接的道路連通起來。

如有4個城市,其中1和2有道路,3和4有道路。

那麼1 2可以相通,3 4可以相通,其他情況均不行。

簡單的思考可以發現,如果我們把有通路的記為同一堆,只需判斷a和b是否在同一堆裡即可。

所以我們現在要實現的就是維護他們之間的連通關係。

為了查詢的方便,我們用一堆裡面的某乙個城市當作這個堆的代表(老大),我們判斷a和b即判斷他們的老大是否相同。這個老**擇誰其實是無所謂的,我們一般用這個堆裡面的第乙個元素就當這個堆的老大。

現在我們來看看到底如果操作

主要說明元素的查詢合併

查詢之前我們需要把每乙個pre[x]初始化,表示它自己就是他所在堆的老大

for

(int i=

1;i<=n;i++

) pre[i]

=i;

我們用pre[x]表示x的上級(不一定是老大)一直向上找,直到pre[x]=x就可以知道x就是x所在堆的老大

int

findroot

(int x)

但這樣有乙個弊端,就是同乙個x會被查詢很多次,所以我們可以用乙個小技巧,用pre[x]來記錄它盡量上級的乙個上級

int

findroot

(int x)

這樣我們就維護可以查詢到x的老大是誰,如果有一條路把x和y連起來了,那麼我們就需要把x和y所在的兩個堆合併起來。

其中的x和y分別是兩個堆的root

void

mix(

int x,

int y)

牛客14685

/*

* @description:

* @autor: kadia

* @date: 2020-06-01 18:23:52

* @lasteditors: kadia

* @lastedittime: 2020-06-01 20:01:29

* nk

*/#include

using

namespace std;

int pre[

100005];

intfindroot

(int x)

void

mix(

int x,

int y)

intmain()

} cout <<

--all << endl ;

return0;

}

資料結構之並查集

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

資料結構之並查集

覺得很不錯的參考資料引用一下 陣列實現 合併操作代價高,可達o n 2 鍊錶實現 樹結構實現 查詢與合併的平均時間複雜度為o log 2 n 與樹的深度有關,優化 降低時間複雜度 按秩合併 若h b h b,則將b樹作為a樹的子樹。帶路徑壓縮的查詢演算法 改變結點所指方向以減小深度,查詢路徑時 走兩...

資料結構之並查集

1.將兩個集合合併。2.詢問兩個元素是否在乙個集合當中。複雜度近乎o 1 基本原理 每個集合用一棵樹來表示。樹根的編號就是整個集合的編號。每個節點儲存它的父節點,p x 表示x的父節點。問題1 如何判斷樹根 if p x x 問題2 如何求x的集合編號 while p x x x p x 問題3 如...