20200720_第一個Java程式和環境配置
阿新 • • 發佈:2020-09-11
並查集
一、關於並查集
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]) returnx; 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);