並查集詳解

2021-09-10 01:38:48 字數 3668 閱讀 4302

大佬請繞道 (~ ̄▽ ̄)~

1.什麼是並查集?

所謂並查集就是union+find+set

2.為什麼要有並查集?

2.1 為什麼會有並查集?

在有些程式設計題中,會有這種需求:

求家族數舉例。如果我們知道子節點以及對應的父節點,如果有血緣關係的就被看做是乙個家族,那麼該怎麼知道輸入中家族的數目呢?

一般的思維是:

在演算法中,有一種較為簡單的方法可以幫助我們解決這個問題,那就是並查集。如果我們有幾組輸入(1,2)(1,3)(4,5)那麼我們可以將其合併成(1,2,3)(4,5)。那麼得到的結果就是有兩個家族。但是問題關鍵是怎麼實現這個合併 和 查詢的過程呢?而且集合又該怎麼體現呢?

2.2 如何實現合併過程?

3.簡單案例

3.1 需求

輸入:兩個整數n,m,分別代表的是總人數和待輸入的父子關係。接下來輸入m行,每行的資料樣式是:a,b。其代表的意思是:a 是 b 的兒子。

輸出:輸出有多少個家族?。

3.2 **

​#include 

#define maxn 1000

int n,m;

//總人數 好朋友組數

int father[maxn]

;//初始化操作

void

init()

}int

findfather

(int x)

return x;

}void

union

(int a,

int b)

}int

main()

int group = n;

for(i =

1;i<= n;i++

)printf

("\ngroup = %d"

,group)

;}

3.3 測試用例
3 2

1 3

3 45 3

1 43 5

4 2

5 34 2

1 43 5

6 41 4

3 54 2

5 6

3.4 執行結果

使用測試用例:

6 4

1 43 5

4 25 6

表明這裡有6個人,其中 1 是 4的兒子;3是5的兒子… 5是 6的兒子。那麼最後的輸出就是。這裡一共有兩個家庭。

而輸出 的4 2 5 2 6 6表示的意思就是:father[1] = 4father[5] = 6,father[6] = 6

4.注意事項

4.1 這裡給出需要注意的幾點:

4.2下面再給出一道上題的改編題。請使用並查集求解。

#include

#include

#include

#define maxn 1005

using namespace std;

struct family

;//標記每個節點的資訊

struct node

; family fam[maxn]

;node node[

10000];

//用於標記每個節點的sun節點

//尋找根節點

intfindsun

(int a)

return a;

}//合併兩個節點

void

unionsun

(int a,

int b)

intmain()

int minvalue ;

for(i =

0;i< n;i++)if

(fam[i]

.mother!=-1

)for

(j =

0;j< childnum;j++

) cin >> fam[i]

.estatenum >> fam[i]

.area;

//合併自身

unionsun

(fam[i]

.id,minvalue)

;//合併父母

if(fam[i]

.father!=-1

)unionsun

(fam[i]

.father,minvalue);if

(fam[i]

.mother!=-1

)unionsun

(fam[i]

.mother,minvalue)

;//合併孩子

for(j =

0;j< childnum;j++)}

cout <<

"\nthe information of every nodes' sun:"

<<

"\n"

;for

(i =

1;i<

10000

;i++)}

//找出有幾個家庭

int familycount =0;

for(i =

1;i<

10000

;i++)}

cout <<

"familycount = "

<

"\n"

;}

10

6666

5551

5552

17777

1100

1234

5678

9012

10002

2300

8888-1

-101

1000

2468

0001

0004

12222

1500

7777

6666-1

023003721-1

-112333

2150

9012-1

-131236

1235

1234

1100

1235

5678

901201

502222

1236

2468

26661

6662

1300

2333-1

3721

36661

6662

6663

1100

12333-1

3721

36661

6662

6663

1100

5. 高階案例

這裡我使用幾道簡單的pat 1114的題目作為案例,進行講解。

並查集詳解

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

詳解並查集

並查集主要用來求解不相交集合的問題,主要針對於合併和查詢兩種演算法。並查集的實現主要包含了三個部分 並查集的初始化是對單個資料建立了乙個單獨的集合,每個集合應該包含以下兩個資料 由以上兩個資料,一般的並查集的結構一般有兩種表示形式 結構體構造如下 define max 50 struct node ...

並查集詳解

看大佬的形象解釋 並查集 按我現在對這個的理解 就是給你一堆數,然後給你兩個兩個數的關係,然後關係的傳遞性 連帶性 這些數就都有了關係 有關係的數組成乙個陣列,然後輸出這個一維陣列,裡面有幾個沒關係的陣列 應該怎麼做呢?第一種解釋是 每給兩個數就把乙個數當成祖宗,把另乙個數當成孩子,然後給了孩子和另...