並查集入門

2021-10-08 13:21:09 字數 1481 閱讀 9764

1.並查集是一種樹形的資料結構,顧名思義,它用於處理一些不交集的合併查詢問題。 它支援兩種操作:

查詢(find):確定某個元素處於哪個子集;

合併(union):將兩個子集合並成乙個集合。

初始化

void

makeset

(int size)

查詢

int

find

(int x)

合併

void

unionset

(int x,

int y)

2.優化並查集

顯然查詢效率實在太低。為什麼呢?因為我們使用了太多沒用的資訊,我的祖先是誰與我父親是誰沒什麼關係,這樣一層一層找太浪費時間,不如我直接當祖先的兒子,問一次就可以出結果了。甚至祖先是誰都無所謂,只要這個人可以代表我們家族就能得到想要的效果。 把在路徑上的每個節點都直接連線到根上 ,這就是路徑壓縮

int

find

(int x)

以上就是最基本的並查集,而在題目中往往不會如此出題

例如2020多校第二場1001簽到題

題目大意:給你n個房子,每個房子m的亮度,再給你一些可以聯通的房子的序號,每次你選擇一些聯通的房子亮度全部減一。直到所有房子亮度為0(亮度為0的房子不可再選擇)

求最少的運算元

思路:暴力

明顯選擇每次最大的連通塊,減到不能減後**成小連通塊,再繼續選擇最大連通塊是可以得到正確結果的,但是在刪除亮度為0的房子時,並查集就難以維護了(反正我不會)

再思考,當把從最大連通塊開始進行暴力操作後,留下的小連通塊是更亮的,於是我們可以反過來思考,從最亮的房子(x)開始判斷 ,依次遍歷這個房子所能夠聯通的房子(y),如果 y 在 x 之前加入且 x 和 y 不連通則將 x 和 y 合併(此時y的樹根亮度減去x亮度,因為把x加入這個連通塊就多操作了x次),並將 y 所在連通塊的樹根的父親設為 x(x成為這個連通塊的新樹根)這樣我們就可以算出每乙個點對答案的貢獻,最後把所有貢獻加一遍就好了

主要**如下

ll res =0;

for(

int i =

1; i <= n;

++i)

} isf[house[i]

.id]=1

;}for(

int i =

1; i <= n;

++i) res +

= light[i]

;

注意用vector存邊後,記得清除vector。

就這樣簽到題寫完了

並查集描述及**出自於

oiwiki

並查集入門

簡述 其實並查集顧名思義就是有 合併集合 和 查詢集合 兩種操作的關於資料結構的一種演算法。並查集演算法不支援分割乙個集合。演算法 用集合中的某個元素來代表這個集合,該元素稱為集合的代表元。乙個集合內的所有元素組織成以代表元為根的樹形結構。對於每乙個元素 parent x 指向x在樹形結構上的父親節...

並查集入門

簡述 其實並查集顧名思義就是有 合併集合 和 查詢集合 兩種操作的關於資料結構的一種演算法。並查集演算法不支援分割乙個集合。演算法 用集合中的某個元素來代表這個集合,該元素稱為集合的代表元。乙個集合內的所有元素組織成以代表元為根的樹形結構。對於每乙個元素 parent x 指向x在樹形結構上的父親節...

並查集入門(普通並查集 帶刪除並查集 關係並查集)

什麼是並查集?通俗易懂的並查集詳解 普通並查集 基礎並查集 例題 題解 how many tables problem description lh boy無聊的時候很喜歡數螞蟻,而且,還給每乙隻小螞蟻編號,通過他長期的觀察和記錄,發現編號為i的螞蟻會和編號為j的螞蟻在一起。現在問題來了,他現在只有...