欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++初級并查集知識點總結(jié)

 更新時間:2019年07月08日 14:17:34   作者:Alex___Wei  
在本篇文章里小編給各位分享的是關(guān)于c++初級并查集知識點以及實例代碼內(nèi)容,有需要的朋友們學(xué)習(xí)下。

并查集是一種樹型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不交集的合并及查詢問題。

有一個聯(lián)合- 查找算法定義了兩個用于此數(shù)據(jù)結(jié)構(gòu)的操作:

  • Find :確定元素屬于哪一個子集。它可以被用來確定兩個元素是否屬于同一子集。
  • Union:將兩個子集合并成同一個集合。

并查集主要運用在合并元素以及查詢兩個元素是否在同一集合的問題,在信息學(xué)競賽中廣泛涉及

初始化:

一開始,每一個元素都是一個集合,打個比方,每個人所在的 " 家族 " 只有他一個人。我們還需要一個 f 數(shù)組,里面存的是他的 “父親” 的編號,初始值為 f[1]=1,f[2]=2……f[n]=n,如圖

2、find函數(shù):find(a)是用來查找a的“祖先”的,例如,我們要查找 a 的祖先,就要去找 a 的父親的父親……,直到有個人 b ,他的父親就是他自己,那么 b 就是 a 的祖先代碼如下:int find (int x){    if(f[x] == x) return x;//如果x的父親就是他自己,則x為a的祖先 else return find (f[x]);//否則a的祖先 就是a的父親的祖先}int x=find(a);find函數(shù):find(a)是用來查找a的“祖先”的,例如,我們要查找 a 的祖先,就要去找 a 的父親的父親……,直到有個人 b ,他的父親就是他自己,那么 b 就是 a 的祖先代碼如下:int find (int x){    if(f[x] == x) return x;//如果x的父親就是他自己,則x為a的祖先 else return find (f[x]);//否則a的祖先 就是a的父親的祖先}int x=find(a);

union函數(shù):

union(a,b) 就是合并 a,b 這兩個人所在的家族,只需要把 a的祖先的父親 指向 b的祖先

如何合并?我們設(shè) u=find(a),v=find(b) , 只要將 u,v 其中一個人的父親編號指向另外一個人就行了,例如 f[u]=v

代碼如下:

void Union (int a,int b)//因為union是c++的保留字,所以只好大寫u

{

  int u= find(a), v= find(b);//尋找a,b的祖先

  f[u]=v;//合并家族

}

Union (a,b);

在合并的時候還有一個注意點:為什么不能直接把 a 的父親指向 b ?因為這樣并不能合并完全,a 的父親, a 的父親的父親……,都不能合并到 b 的家族里(想一想,為什么?),如圖

5、查詢兩個元素是否在同一集合里:查詢 a,b 是否在同一集合里,就是看他們的祖先是否相等,若相等則在同一集合里,否則就不在代碼如下:if( find(a) == find(b) ) cout<<"Y\n"; //如果祖先相等就輸出“Y”else cout<<"N\n"; //否則輸出“N”查詢兩個元素是否在同一集合里:查詢 a,b 是否在同一集合里,就是看他們的祖先是否相等,若相等則在同一集合里,否則就不在代碼如下:if( find(a) == find(b) ) cout<<"Y\n"; //如果祖先相等就輸出“Y”else cout<<"N\n"; //否則輸出“N”

例題:

 至此,你應(yīng)該對并查集有了初步的了解,是時候上例題了

題目描述

如題,現(xiàn)在有一個并查集,你需要完成合并和查詢操作。

輸入輸出格式

輸入格式:

第一行包含兩個整數(shù)N、M,表示共有N個元素和M個操作。

接下來M行,每行包含三個整數(shù)Zi、Xi、Yi

當(dāng)Zi=1時,將Xi與Yi所在的集合合并

當(dāng)Zi=2時,輸出Xi與Yi是否在同一集合內(nèi),是的話輸出Y;否則話輸出N

輸出格式:

如上,對于每一個Zi=2的操作,都有一行輸出,每行包含一個大寫字母,為Y或者N

其實,這道題目就是把上面幾個步驟綜合在一起,代碼如下

并查集的路徑壓縮

路徑壓縮,顧名思義,就是將本來要很多步完成的事情壓縮成一步

因為我們每次 find(a) 都要消耗 O (a 的層數(shù) ) 的時間,如果數(shù)據(jù)構(gòu)造成一條鏈,則每次 find 都需要 O(n) 的時間,這是我們不希望看到的

所以,我們可以把 f 數(shù)組的性質(zhì)改變一下 f[a] 指向的編號變?yōu)?nbsp;a 的祖先

代碼該怎么寫呢?我們只需要在 find 函數(shù)里把

return find (f[x]);

變成

return f[x]=find(f[x]);

就可以了

這樣每一次 find 都會使路徑上的每個 f[x] 指向 x 的祖先,每一次 find 也就只需要 1 步就行了(除非被合并過,那也只需要 2 步),這就是路徑壓縮的實質(zhì)

相關(guān)文章

  • C++處理鍵盤輸入的方法

    C++處理鍵盤輸入的方法

    這篇文章主要介紹了C++處理鍵盤輸入的方法,是C++程序設(shè)計中非常實用的技巧,需要的朋友可以參考下
    2014-10-10
  • Qt網(wǎng)絡(luò)編程之TCP通信及常見問題

    Qt網(wǎng)絡(luò)編程之TCP通信及常見問題

    這篇文章主要為大家詳細(xì)介紹了Qt網(wǎng)絡(luò)編程之TCP通信及常見問題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++類的空指針調(diào)用成員函數(shù)的代碼

    C++類的空指針調(diào)用成員函數(shù)的代碼

    這篇文章主要介紹了C++類的空指針調(diào)用成員函數(shù),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • C++雙向鏈表實現(xiàn)簡單通訊錄

    C++雙向鏈表實現(xiàn)簡單通訊錄

    這篇文章主要為大家詳細(xì)介紹了C++雙向鏈表實現(xiàn)簡單通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Linux C 獲取進程退出值的實現(xiàn)代碼

    Linux C 獲取進程退出值的實現(xiàn)代碼

    本篇文章是對在Linux下使用c語言獲取進程退出值的方法進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++樹之遍歷二叉樹實例詳解

    C++樹之遍歷二叉樹實例詳解

    這篇文章主要給大家介紹了關(guān)于C++樹之遍歷二叉樹的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • include包含頭文件的語句中,雙引號和尖括號的區(qū)別(詳解)

    include包含頭文件的語句中,雙引號和尖括號的區(qū)別(詳解)

    下面小編就為大家?guī)硪黄猧nclude包含頭文件的語句中,雙引號和尖括號的區(qū)別(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 詳解C++中的成員訪問運算符和指針到成員運算符

    詳解C++中的成員訪問運算符和指針到成員運算符

    這篇文章主要介紹了C++中的成員訪問運算符和指針到成員運算符,即. 和 ->以及.* 和 ->*的使用方法,需要的朋友可以參考下
    2016-01-01
  • C++如何用智能指針管理內(nèi)存資源

    C++如何用智能指針管理內(nèi)存資源

    這篇文章主要介紹了C++如何用智能指針管理內(nèi)存資源,幫助大家更好的理解和使用c++開發(fā),感興趣的朋友可以了解下
    2020-08-08
  • VS報錯C1189及MSB3721解決方法

    VS報錯C1189及MSB3721解決方法

    在使用VS進行CUDA編譯時出現(xiàn)錯誤,本文主要介紹了VS報錯C1189及MSB3721解決方法,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06

最新評論