1. 程式人生 > >並查集學習總結

並查集學習總結

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)return
false; 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

回來找時間再把例題的具體內容補上...

(未完待續)

並查集學習總結