普通並查集由三部分組成:
(1)乙個整型陣列
(2)初始化函式,inin
(3)乙個查詢函式,find
(4)乙個合併函式,join
—>1.1 初始化,inin
使每個元素自身成為乙個集合,即pre[i]=i。
–>1.2 查詢函式,findvoid
inin
(int x)
//初始化
}
查詢乙個元素的根節點。
–>1.3 合併函式,joinint
find
(int x)
return r;
//返回根節點
}
把兩個元素的根節點合併,形成樹
到這裡,我們會發現,在執行上面的**後,形成的樹的深度可能會太大,一字長蛇陣也是有可能的,這樣查詢起來的效率就會很低,當然,在一些題中,資料量小,效率就無所謂,但在一些資料量非常大的題中,效率就很重要。而且形成的樹可能會退化。為了避免這個問題,我們對**做一些改進。void
join
(int a,
int b)
}
壓縮路徑:
意思就是讓所有的節點都指向根節點,使樹的層數在維持一種較低的水平,從而提高查詢效率。
**實現:
例題:#define n 55005
int pre[n]
;//樹的節點
int rank1[n]
;//樹的深度
int n, m;
void
inin
(int x)
//初始化
}int
find
(int x)
//查詢結點x的根結點
else
return pre[x]
=find
(pre[x]);
//遞迴查詢 此**相當於 先找到根結點rootx,然後pre[x]=rootx
}void
join
(int a,
int b)
//節點和並
else
pre[fa]
= fb;
}}
在三角洲不同地區生活的人們有自己信仰的圖騰,為了避免冒犯到他們,首腦們現在想知道他們最多可能有多少種圖騰。但這對他們來說是件無趣的事,所以現在任務交到了你的身上。 當你看到兩個地區的人們在膜拜同一外觀的石像時,就可以斷定他們擁有同樣的圖騰。已知三角洲共有n(n <= 50000)塊區域,你看到了m(m<=n(n-1)/2)組地區的人們在膜拜同樣的石像,現在請問他們至多有多少種圖騰。
input有多組資料。對於每組資料:
第一行:兩個整數n和m。
以下m行:每行包含兩個整數i和j,表示你發現i地區和j地區的人們在膜拜同樣的石像。地區編號從1到n。
輸入的最後一行中,n = m = 0。
output對於每組測試資料,輸出一行,輸出資料序號( 從1開始) 和圖騰的最大數量。(參見樣例)
sample input10 9
1 21 3
1 41 5
1 61 7
1 81 9
1 10
10 4
2 34 5
4 85 8
0 0
sample outputcase 1: 1
case 2: 7
#include
#include
using namespace std;
#define n 55005
int pre[n]
;//樹的節點
int rank1[n]
;//樹的深度
int n, m;
int sum;
void
inin
(int x)
//初始化
}int
find
(int x)
//查詢結點x的根結點
else
return pre[x]
=find
(pre[x]);
//遞迴查詢 此**相當於 先找到根結點rootx,然後pre[x]=rootx
}void
join
(int a,
int b)
//節點和並
並查集演算法的用途;
1、維護無向圖的連通性。支援判斷兩個點是否在同一連通塊內,和判斷增加一條邊是否會產生環。
2、用在求解最小生成樹的kruskal演算法裡。
下面是大佬對並查集的講解:
普通並查集
並查集入門(普通並查集 帶刪除並查集 關係並查集)
什麼是並查集?通俗易懂的並查集詳解 普通並查集 基礎並查集 例題 題解 how many tables problem description lh boy無聊的時候很喜歡數螞蟻,而且,還給每乙隻小螞蟻編號,通過他長期的觀察和記錄,發現編號為i的螞蟻會和編號為j的螞蟻在一起。現在問題來了,他現在只有...
並查集 並查集
本文參考了 挑戰程式設計競賽 和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 ...
普通並查集之宗教問題 題目
題目 宗教問題 第一行輸入n 人數 m 關係數 接著換行輸入m個關係 換行輸入詢問次數q 換行輸入詢問每組詢問對應一組輸出 如果是則輸出yes,否或不一定都輸出no例 5 3 5個人,3個關係12 1說他在自己的教堂裡看到過223 2說他在自己的教堂裡看到過345 4說他在自己的教堂裡看到過5 22...