筆記 並查集

2021-10-02 19:52:04 字數 1797 閱讀 6720

不管後面寫了啥,一定要把最重要的寫在前面:(總記不住)

使用陣列表示並查集:

int father[n]

;

father[i]表示元素i的父親結點

初始情況下,每個元素都是單獨的集合,因此其父結點是自己,這在並查集中被稱為reflexive

for

(int i =

1; i <= n; i++

)

乙個集合中只有乙個根結點,因此反覆地查詢父結點,直到father[x] == x,則x為該集合的根節點。

將兩個集合合併在一起,只需要找到兩個集合的根,將其中乙個根的父結點設為另乙個根即可。因為和 c/c++ 中的union關鍵字衝突,所以函式寫成了uni

void

uni(

int a,

int b)

並查集有一些基礎的常規操作,為了縮短在程式設計考試中減少對「常規」操作的思考時間(雖然也很簡單),故記錄下來,形成自己習慣性的模板**。

題目中常常給定的元素編號是連續的,通常是1~n,因此可以直接將物件 id 作為下標,表示其在並查集中的位置,但是有時候給定的是字串,或是給定的範圍很大,這個時候需要對每個元素重新編號,最好的方式是從序號1開始,用兩個map分別做 id->num 和 num->id 的對映

int

main()

if(idtonum[b]!=0

) tb = idtonum[b]

;else

uni(ta, tb)

;// 合併 ta、tb}.

....

..}

有時候題目給定了元素的編號,並且這個編號在合理的範圍內,但是編號不連續,因為並查集建立完成後需要遍歷所有元素以找出不同集合,所以,如果是不連續的元素編號則可以使用unordered_set記錄輸入的元素,之前想過用vector但是可能出現重複輸入一樣的編號,所以不適用。

unordered_set<

int> s;

string a, b;

while

(t--

)for

(auto it : s)

在並查集建立好之後,需要找出各個集合對之做操作。

for

(int i =

1; i < pos; i++

)

有時候需要將乙個集合作為乙個結構去看,其中需要儲存一些題目要求的資料,並做排序。則要用到 map 和 vector

struct node ;.

....

.map<

int, node> mp;

for(

int i =

1; i < pos; i++

)vector ans;

for(

auto it : mp) ans.

push_back

(it.second)

;sort

(ans.

begin()

, ans.

end(

), cmp)

;

並查集 並查集

本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...

並查集學習筆記

並查集是一種用來管理資料分組狀況的資料結構,可以進行合併操作,但無法進行分割。並查集的結構 並查集也是用樹形結構來實現的,但不是二叉樹。每個資料,元素對應乙個節點,每個組對應一棵樹。並查集的實現 並查集有幾個基本操作初始化 查詢樹的根 合併x,y所屬集合 判斷x,y是否屬於同一集合。查詢是查詢樹的根...

並查集 學習筆記

並查集是由一組互不相交的集合組成的乙個集合結構,並在此集合上定義了運算union和find。即並查集中的元素本身是集合,他們是某個集合的子集,並查集是由這些集合組成的集合結構。並查集上有兩個最基本的運算,find和union。函式find搜尋給定元素i所在的子集合,並返回該自己喝 union運算將兩...