就例如一個非常簡單的題~
有一堆人 其中某些人是朋友
有如下的規則 如果A和B是朋友 B和C是朋友 那么A和C也是朋友~
最后我們有n次的查詢 每次查詢問其中兩個人是不是朋友?
這個題我們就可以用到集合的思想~
例如A和B是朋友 我們可以把A和B放到一個集合里~
C和D是朋友 我們就把C和D放到一個集合里~
如圖
(原諒只會人工畫圖的笨比)
但如果我們假設A和C也是好朋友
我們就把這兩個集合合並起來~
就是這個樣子~我們對所有的“朋友對”進行這樣的操作 就會把他們分到一個個集合里 這時候查找他們是不是好朋友就很輕松了~
以上這些 就是並查集的思想:
當然我們通過c語言實現並查集也很簡單
借助數組!
首先我們定義一個數組!
fa[maxn]
fa代表father的意思 父親
fa[1]=2就代表1的父親是2
為什么這么做呢!
因為並查集是一種樹狀的數組
例如剛才那個例題 我們怎么做才算是把AB,CD分別放到一個集合里呢!
很簡單 就是讓A的父親是B,C的父親是D
fa[A]=B,fa[C]=D
通過這種方式!我們就形象的把A和B連在一起 C和D連在了一起(這樣來代表他們是一個集合里的)
之后我們如果知道了A和C是好朋友
我們如何合並(AB)和(CD)這兩個集合呢
很簡單 我們首先查找A的祖先 然后查找C的祖先
然后讓A的祖先 是C的祖先的父親
fa[A的祖先]=C的祖先
如圖:
這樣一個非常簡單的並查集就做好了~
那么我們如何知道查詢呢!
就例如查詢A和C是不是好朋友
我們首先找A的祖先
A的父親=B,再找B的父親=D 所以A的祖先就是D!
那么我們再找C的祖先
C的父親=D(這時候上面沒人了)所以C的祖先就是D!
那么如果A的祖先和C的祖先是一個人!!
如圖 就可以證明 A和C在同一個集合中
----------------------------------------------------------------
以上 就是我們一個簡單並查集的兩大功能
1合並兩個集合
2查找
----------------------------------------------------------------
可能這時候你有了一點點小問題
我們該如何知道某個人上面是不是沒人了!
(例如上面我們怎么知道C的父親=D,D就是他的祖先,在上面就沒人了呢?)
我們可以在初始化上做操作!
fa[i]=i;
我們初始化上 讓每個人的祖先都是他自己!
而在上面集合(ABCD)中 我們知道祖先是D D作為最大的 他上面沒有其他比他輩大的了
所以按照我們初始化的結果!D的祖先還是D,是他自己
因此 我們只需要找 某個元素的祖先是不是自己 就可以完成祖先的判斷
如圖:
上一波代碼實現:
通過三目運算符判斷 如果x==x的父親 那么x就是祖先 如果不是 那么讓接着往上尋找父親的父親 直到找到一個x=x的父親的節點 作為祖先
以上為初始化實現(巨簡單是不是)
那么如何合並兩個集合呢!
也非常簡單
首先找到x的祖先 然后找到y的祖先 讓(x的祖先)的父親是(y的祖先)即可!
參考上面例題哦~
以上
就是一個非常簡單的並查集啦~
當然還可以進一步的優化等等
今天做題做到了並查集相關的內容~簡單介紹一下關於並查集的東西
我是蒟蒻lsr!下期博客見=-=