基本資料結構 並查集 C

2022-05-11 16:41:28 字數 1489 閱讀 5951

並查集,在一些有n個元素的集合應用問題中,我們通常是在開始時讓每個元素構成乙個單元素的集合,然後按一定順序將屬於同一組的元素所在的集合合併,其間要反覆查詢乙個元素在哪個集合中。這一類問題近幾年來反覆出現在資訊學的國際國內賽題中,其特點是看似並不複雜,但資料量極大,若用正常的資料結構來描述的話,往往在空間上過大,計算機無法承受;即使在空間上勉強通過,執行的時間複雜度也極高,根本就不可能在比賽規定的執行時間(1~3秒)內計算出試題需要的結果,只能用並查集來描述。

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

摘自網路↑

下面主要是自己的感悟emm可能有些不對的地方歡迎指出

並查集,顧名思義,方便的主要就是合併和查詢兩種基本操作,然後說一下並查集的基本操作:

fa[i]表示點i的父節點,根節點的父節點是它自己。

這裡就涉及到初始化,因為開始的時候每乙個點都是一棵獨立的樹,它們都是根節點,所以它們要把fa[i]=i。

另外sz[i]表示這一棵樹的深度,只有根節點的sz值才是有效的,可能有些題目裡不會涉及但是還是打上來哈

void init()

}

合併:

在實現合併操作之前, 我們先要想乙個問題:合併兩棵樹,是不是把這兩棵樹上任意兩個節點產生聯絡就可以了?

很明顯不是。

我們的合併操作,應該是要把其中一整棵樹都掛在另一棵樹的根節點上,也就是把a樹的根節點的父節點設定為b樹的根節點,就完成了a,b兩樹的合併。

所以現在的問題是取根節點。

初始寫法:

int get(int x)

但是!如果這麼寫,每次查詢根節點都要花費太多的時間,如果題目特殊構造一條鏈型的樹,那麼就會出現tle.

怎麼優化呢?

其實,在每次查詢根節點所途徑的路上遇到的所有節點,我們都可以把它們直接掛到根節點上,這樣下次查詢的時候就會方便許多了。

最終寫法:

int get(int x)

那麼接下來才是實現合併的操作。

所謂合併,就是如上所述,把其中一棵樹的根節點掛到另一棵樹的根節點上,實現合併,那麼就很容易實現:

void merge(int x,int y)

bool ask(int x,int y)

下面貼上完整**:

#includeusing namespace std;

int n,fa[10001],z,x,y,m,sz[10001];

void init()

}int get(int x)

void merge(int x,int y)

bool ask(int x,int y)

int main()

else

if(ask(x,y))cout<<"y"

資料結構 並查集

並查集,顧名思義,合併 查詢 集合 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。對於概念等等的這裡不再贅述,直接講解應用。應用1 判斷圖中有多少聯通分量 或者圖是否聯通 聯通分量 1 hdu 1213 應用2 判斷圖是否...

資料結構 並查集

time limit 1000ms memory limit 65536k 某城市有n個人,現在給定關於n個人的m條資訊,m條資訊是兩個人在同乙個小區,根據所給資訊,判斷這個城市最多可能有多少個小區。n個人編號為1 n。多組輸入。每組第一行有兩個整數n,m 2 n 50000,0 m n 2 接下來...

資料結構 並查集

一 基本概念 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組的元素所在的集合合併。在一些有n個元素的集合應用問題中,通常是在開始時讓每個元素構成乙個單元素的...