1. 程式人生 > 實用技巧 >20200720_第一個Java程式和環境配置

20200720_第一個Java程式和環境配置

並查集

一、關於並查集

1. 定義

並查集(Disjoint-Set)是一種可以動態維護若干個不重疊的集合,並支援合併查詢兩種操作的一種資料結構。

2. 基本操作

1. 合併(Union/Merge):合併兩個集合。
2. 查詢(Find/Get):查詢元素所屬集合。
實際操作時,我們會使用一個點來代表整個集合,即一個元素的根結點(可以理解為父親)。

3. 具體實現

我們建立一個數組fa[ ]pre[ ]表示一個並查集,fa[i]表示i的父節點。
初始化:每一個點都是一個集合,因此自己的父節點就是自己fa[i]=i
查詢:每一個節點不斷尋找自己的父節點,若此時自己的父節點就是自己,那麼該點為集合的根結點,返回該點。

修改:合併兩個集合只需要合併兩個集合的根結點,即fa[RootA]=RootB,其中RootA,RootB是兩個元素的根結點。

路徑壓縮:
實際上,我們在查詢過程中只關心根結點是什麼,並不關心這棵樹的形態(有一些題除外)。因此我們可以在查詢操作的時候將訪問過的每個點都指向樹根,這樣的方法叫做路徑壓縮,單次操作複雜度為O(logN)O(logN)。
結合下圖食用更好(圖為狀態壓縮的過程):

二、程式碼實現

初始化的模板:

for(int i=1;i<=n;i++) pre[i]=i;

查詢的模板(含路徑壓縮):

int Find(int x){
    if(x==pre[x]) return
x; return pre[x]=Find(pre[x]); }

合併的模板:

void merge(int x,int y){
    int fx=Find(x),fy=Find(y);
    if(fx!=fy) pre[fx]=fy;
}
//主函式內
merge(a,b);