查詢2個村莊之間是否有連線的路
連線2個村莊
並查集能夠辦到查詢、鏈結的均攤時間複雜度都是o(α(n)),α(n)<5
並查集非常適合解決這類「連線」相關的問題
查詢(find):查詢元素所在的集合(這裡的集合並不是特指set這種資料結構,是指廣義資料集合)
合併(union):將兩個元素所在的集合合併成為乙個集合
quick find
查詢(find)的時間複雜度:o(1)
合併(union)的時間複雜度:o(n)
quick union
查詢(find)的時間複雜度:o(logn),可以優化至o(α(n)),α(n) < 5
合併(union)的時間複雜度:o(logn),可以優化至o(α(n)),α(n) < 5
0、1、3屬於同一集合
2單獨屬於乙個集合
4、5、6、7屬於同一集合
// 查詢v所屬的集合(根節點)
intfind
(int v)
;// 合併v1、v2所屬的集合
void
union
(int v1,
int v2)
;// 檢查v1、v2是否屬於同乙個集合
基於size的優化:元素少的樹嫁接到元素多的樹
基於rank的優化:矮的樹嫁接到高的樹
;}路徑**(path spliting)
路徑減半(path halving)
基於rank的優化
path halving 或 path spliting
方案一:通過一些方法將自定義型別轉為整形後使用並查集(比如生成雜湊值)
方案二:使用鍊錶+對映(map)
genericunionfind
uf =
newgenericunionfind
<
>()
;student stu1 =
newstudent(10
,"jack");
student stu2 =
newstudent(18
,"rose");
uf.makeset
(stu1)
;uf.
makeset
(stu2)
;uf.
union
(stu1, stu2)
;uf.
issame
(stu1,sut2)
;
public
class
genericunionfind
// 找到v的根節點
private node
findnode
(v v)
return node;
}public v find
(v v)
public
void
union
(v v1, v v2)
else
if(p1.rank > p2.rank)
else
}public
boolean
issame
(v v1, v v2)
private
static
class
node }}
泛型的並查集,效率會低一點,時間是整數並查集的兩倍,但是換來的是通用性,如果自定義物件有唯一標示(例如id),就可以直接使用整數並查 資料結構 並查集
並查集,顧名思義,合併 查詢 集合 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。對於概念等等的這裡不再贅述,直接講解應用。應用1 判斷圖中有多少聯通分量 或者圖是否聯通 聯通分量 1 hdu 1213 應用2 判斷圖是否...
資料結構 並查集
time limit 1000ms memory limit 65536k 某城市有n個人,現在給定關於n個人的m條資訊,m條資訊是兩個人在同乙個小區,根據所給資訊,判斷這個城市最多可能有多少個小區。n個人編號為1 n。多組輸入。每組第一行有兩個整數n,m 2 n 50000,0 m n 2 接下來...
資料結構 並查集
一 基本概念 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組的元素所在的集合合併。在一些有n個元素的集合應用問題中,通常是在開始時讓每個元素構成乙個單元素的...