并查集


用途

主要用于解決判斷兩結(jié)點是否能連通之類的問題。
  
思想

建立并查集數(shù)組set[],初始化全部置-1。set[b]=a代表結(jié)點b的父結(jié)點為a。判斷兩結(jié)點是否連通,只要依次找到兩結(jié)點的根結(jié)點并判斷是否相同即可。若不同,將一結(jié)點的根節(jié)點連接作為另一節(jié)點根節(jié)點的子樹,即可完成連通操作。

/*尋根*/
int findRoot(int x)
{
    while(set[x]!=-1)
        x=set[x];
    return x;
}

/*連通操作*/
void Union(int a,int b)
{
    set[findRoot(b)]=findRoot(a);
}

注意
?
  用以上方法操作時,一旦數(shù)據(jù)過多,往往會造成運行超時的結(jié)果,原因在于并查集樹過高,搜索根節(jié)點時間長。下面提供兩種解決思路:
  
1.路徑壓縮
  變更set[i]值的含義,將set[i]直接指向包含結(jié)點i的樹的根節(jié)點,使每次查找根節(jié)點所需時間大大減少。具體做法為:每一次尋根的時候,變更set[i]值為根節(jié)點。經(jīng)過路徑壓縮后效率可以達到O(N)。

/*路徑壓縮*/
int findRoot(int x)
{
    /*注意x即為根節(jié)點的情況,此時直接返回x即可*/
    if(set[x]==-1)
        return x;
    else
    {
        int temp=x;     //先將x的值保存下來
        while(set[x]!=-1)
            x=set[x];
        set[temp]=x;    //更新set[]
        return x;
    }
}

2.按秩歸并
  壓縮路徑存在的一個問題是會破壞樹的形狀,這是可以考慮使用按秩歸并的方法。
  對于兩顆高度不一的樹,若將高樹并到矮樹上,則得到的樹高度為原高樹高度加一,為了不使樹一直增高,我們采取的做法是每一次合并都將矮樹合并到高樹上(通過根節(jié)點的值來記錄樹高,即set[root]=-樹高)。當然也可以從樹的規(guī)模入手,將小樹歸并到大樹上。
  最壞情況下樹高O(logN),按秩歸并的復雜度可以低至O(NlogN)。

/*比高度,set[root]存儲高度*/
void Union(int a,int b)
{
    int aRoot=findRoot(a);
    int bRoot=findRoot(b);
    if(set[aRoot]<set[bRoot])       //若a為高樹
        set[bRoot]=aRoot;
    else        
    {
        if(set[aRoot]==set[bRoot])  //若樹高相等
            --set[bRoot];    //合并后樹高要加一
        set[aRoot]=bRoot;
    }
}
/*比規(guī)模,set[root]存儲規(guī)模*/
void Union(int a,int b)
{
    int aRoot=findRoot(a);
    int bRoot=findRoot(b);
    if(set[aRoot]<set[bRoot])   //a規(guī)模大于b
    {
        set[aRoot]+=set[bRoot];//注意規(guī)模要合并
        set[bRoot]=aRoot;
    }
    else
    {
        set[bRoot]+=set[aRoot];
        set[aRoot]=bRoot;
    }
}

3.以上兩種方法相結(jié)合,可以實現(xiàn)-1s,非常暴力。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 某次參加筆試的最后一題大意如下:給定一組用戶[0..n],以及他們之間的好友關(guān)系,問這些好友構(gòu)成了多少個朋友圈?例...
    Realizability閱讀 1,700評論 0 0
  • 最近看了一篇頗有趣的并查集文章,放在這里推薦一下,順便自己也想總結(jié)一下。http://blog.csdn.net/...
    碧影江白閱讀 950評論 0 0
  • 相關(guān)概念 等價關(guān)系若對于每一對元素(a, b), ![](http://latex.codecogs.com/sv...
    芥丶未央閱讀 528評論 0 0
  • 1.問題描述: 有N個對象,對象間可以連通。假設(shè)有一個命令用來連接兩個對象,將兩個對象傳入該命令就會連接兩者,還有...
    luckygong閱讀 1,135評論 0 0
  • 校運會即將開始 一對對隊伍排好 等待著老師安排 ...
    把愛還給我閱讀 196評論 8 2

友情鏈接更多精彩內(nèi)容