並查集學習總結
阿新 • • 發佈:2018-04-26
urn 過程 判斷 如果 但是 void for 情況 sam
並查集作用:判斷兩個元素是否在一個集合內。
方式:通過記錄每個元素對應的par[x]值來判斷,如果兩者相等,則為同組,否則為不同組。
_rank[maxn]的作用:_rank[i]記錄的是每一個節點所在的樹的高度,查詢的時候意義不大,但是當兩棵樹合並的時候,當樹的高度小的樹連接到樹的高度高的樹會讓樹的整體高度較小,而保證查詢優化。
狀態壓縮:並查集的狀態壓縮通過如下代碼實現:
int find(int x){ if(par[x]==x) return x; }else{ return par[x]=find(par[x]); } }
上面的代碼可以讓所有的節點都直接連到根節點上,這樣無論原本的樹高度為多少,在這樣一次操作後,樹的高度都為2。所以在有狀態壓縮的情況下,_rank的作用非常小,幾乎可以忽略。
模板:
const int maxn=1e5+5; int par[maxn]; void init(int n){ for(int i=0;i<n;i++){ par[x]=i; } } int find(int x){ if(par[x]==x){ return x; }else{ return par[x]=find(par[x]); } } bool unite(int x,int y){ x=find(x); y=find(y); if(x==y)returnfalse; else{ par[x]=y;//此處par[y]=x;也可以 return true; } } bool same(int x,int y){ return find(x)==find(y); }
其中unite函數也可以不返回布爾值,之所以在那裏寫了布爾值,是因為這樣可以判斷是否成功連接,在MST(最小生成樹)的生成過程中使用較為方便。
例題:
1.連通
2.食物鏈
3.真假話
4.反向連通
5.MST
回來找時間再把例題的具體內容補上...
(未完待續)
並查集學習總結