OI學習筆記之資料結構 基礎並查集

2021-09-25 15:29:44 字數 1636 閱讀 7652

**並查集是一種樹型的資料結構,用於處理一些不相交集合的合併及查詢問題。常常在使用中以森林來表示。

一,對並查集的認識

並查集是樹形結構,常常在題目中用來判斷兩個元素是否屬於同乙個集合,每個集合都有乙個特徵性元素稱為這個集合的father,如果兩個元素的father相同,則說明這兩個元素屬於同一集合,若這兩個元素的father不相同,則說明這兩個元素不屬於乙個集合。並查集就是這樣一種支援合併和查詢的樹形資料結構。在題目中的應用有,判斷兩個點是否屬於同乙個聯通塊,最小生成樹kruskal演算法中,判斷加邊是否會有環等。

在考察並查集的題目中,一般我們用乙個f陣列來實現並查集的功能,起初所有的f[i]=i;證明所有元素都是單獨乙個集合。

//並查集初始化

for(

int i=

1;i<=n;i++

) f[i]

=i;

二,並查集的基本操作

1,並查集的合併操作(merge)

簡而言之,就是將兩個元素所在的集合合併成乙個集合,操作簡單,首先我們只需要找到兩個集合的特徵性元素,然後把其中乙個特徵性元素變成另乙個,這樣兩個集合特徵性元素相同,兩個集合就合併在了一起,在merge操作中我們運用到了按秩合併來優化。

inline

void

merge

(int f1,

int f2)

//普通合併

按秩合併:所謂秩就是樹高,按秩合併就是按照秩序合併,起初我們給每個點賦高為一,以後在每次合併的過程中,都用樹高小的指向樹高大的,這樣可以保證樹高不超過log2n,把查詢的最壞複雜度從o(n)減小到o(logn)。

inline

void

merge

(int x,

int y)

return

;}

2,並查集的查詢操作

就是查詢兩個元素是否屬於同乙個集合,首先我們要先找到這兩個元素所在集合的特徵性元素。如果兩個特徵性元素相同,則兩個元素屬於同乙個集合,否則屬於兩個集合,其中我們用到路徑壓縮來優化,路徑壓縮就是在查詢過程中,從此節點到根節點路徑上的所有節點的f全部改為根節點,這樣在下次查詢時,就可以減少遞迴過程從而達到優化的目的。

inline

intfind

(int k)

*:按秩合併和路徑壓縮不可以同時使用,一般我們使用路徑壓縮來優化。

並查集完整**(洛谷p3367)

#include

#include

using

namespace std;

int n,m,f[

10005];

intfind

(int k)

void

merge

(int x,

int y)

intmain()

}return0;

}

祝各位oier noip2019 rp++ score++

OI學習筆記之資料結構 樹狀陣列

樹狀陣列複雜度 o logn 樹狀陣列是一種維護字首和,區間最大值,區間最小值,區間異或和等滿 換律的東西的資料結構,其支援單點修改和區間查詢。樹狀陣列其實並不算一棵樹,它是由陣列 二進位制的操作實現的,只是在實現的過程中我們借助了樹形結構的思想,因此樹狀陣列並不需要建樹等操作。一,認識樹狀陣列 樹...

演算法基礎之資料結構 並查集

題目 合併計算 一共有 n 個數,編號是 1 n,最開始每個數各自在乙個集合中。現在要進行 m 個操作,操作共有兩種 m a b,將編號為 a 和 b 的兩個數所在的集合合併,如果兩個數已經在同乙個集合中,則忽略這個操作 q a b,詢問編號為 a 和 b 的兩個數是否在同乙個集合中 輸入格式 第一...

資料結構之並查集

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