並查集的分析及應用

2021-06-20 08:46:26 字數 1985 閱讀 2953

昨天看了幾篇有關並查集的**,對理解並查集很有幫助,在這裡寫篇部落格來記錄下自己對並查集的簡單理解,以及並查集的簡單運用。

並查集的分析

並查集的概念主要是處理集合問題(或可抽象成集合概念的問題),首先數學上的集合概念做個初步的分析

首先,我們從數學的角度給出等價關係和等價類的定義:

定義1:如果集合s中的關係r是自反的,對稱的,傳遞的,則稱他為乙個等價關係。

——自反:x=x;

——對稱:若x=y,則y=x;

——傳遞:若x=y、y=z,則x=z。?要求:x、y、z必須要同乙個子集中。

定義2:如果r是集合s的等價關係。對於任何x∈s,由[x]r=給出的集合[x]rs

稱為由x∈s生成的乙個r的等價類。

定義3:若r是集合s上的乙個等價關係,則由這個等價關係可產生這個集合的唯一劃分。

即可以按r將s劃分為若干不相交的子集s1,s2,s3,s4,…,他們的並即為s,則這

些子集si變稱為s的r等價類。

劃分等價類的問題的提法是:要求對s作出符合某些等價性條件的等價類的劃分,已知

集合s及一系列的形如「x等價於y」的具體條件,要求給出s的等價類的劃分,符合所

列等價性的條件。(我們上面提到的聯絡,即可認為是乙個等價關係,我們就是要將

集合s劃分成n個聯絡的子集,然後再判斷x,y是否在乙個聯絡子集中。)

這三個基本定義對理解並查集的概念及相應的操作非常有幫助。

並查集的操作主要有三個:

1.劃分等價類,這個在預處理的時候進行,很簡單,就是有多少元素就劃分多少等價類即pre[i]=i,很好理解,為下面的合併做好準備。

2.找根節點(溯源) 我通常用函式root(int x)來實現找x的最終祖先。

3.合併,就是將兩個集合合為乙個集合。

用演算法實現三個方法:

1.預處理

void init(int n)

}

2.溯源

int root(int x)

return pre[x];

}

溯源這裡是有優化的,判斷兩個元素是否屬於同一集合需要o(n)的時間,但這裡可以使用路徑壓縮來進行優化,  路徑壓縮實際上是在找完根結點之後,在遞迴回來的時候順便把路徑上元素的父親指標都指向根結點

3.合併

void merge(int a,int b)

}

合併就是先找到a和b各自的源,然後把源連起來則兩個集合就實現了合併。

一上這三個函式就是並查集的核心思想和方法,以後的解題關鍵就是能將問題抽象成集合並應用並查集來解決了。

並查集的應用

下面我們就以以上並查集的思想解決乙個實際問題來簡單運用一下。

以解決 hdu 1232為例。

題目在這裡就不再贅述了,經過上面的分析,此題就變的很簡單了。

n個頂點連通至少需要n-1條邊,這個是學計算機的都曉得的基礎知識(樹)。此問題總需要的最少邊為total = n-1,每連線兩個不在同一集合中的頂點時,所需要的邊數減一(--total),ok了,最後連完之後的total就是還需要的邊數(也是現在的等價類數目),這個應該也很好理解。

程式實現:

#include int total;

int pre[1001];

void init(int n)

}int root(int x)

return pre[x];

}void merge(int a,int b)

}int main(){

int n,m,i,st,end;

while(scanf("%d",&n) && n){

scanf("%d",&m);

init(n);

total = n-1;

for(i=0;i

並查集的優化及應用

2018 05 01 15 13 08 並查集是乙個時空複雜度非常優越的資料結構,並且通過優化後其複雜度為。並查集的優化主要有兩個方面 路徑壓縮 按rank合併 public class unionfindset public int find int i public boolean union ...

並查集及種類並查集

b站 並查集int find root int x return x int hebing int x,int y return0 檢驗 include using namespace std const int n 100 const int m 200 int parent n deep n i...

並查集的應用

特點 1,都有乙個陣列儲存它的根節點 2,用vis陣列儲存其是否訪問過 3,如果cnt 1 說明該圖是連通的。連通圖中只有根節點的父節點是自身,cnt應該是1 解決的題目 1,題目已經給了圖上頂點之間的關係,通過頂點之間的關係,求連通分量的個數 include stdio.h int bin 100...