並查集演算法不支援分割乙個集合。
用集合中的某個元素來代表這個集合,該元素稱為集合的代表元
。
乙個集合內的所有元素組織成以代表元為根的樹形結構。
對於每乙個元素 parent[x]指向x在樹形結構上的父親節點。如果x是根節點,則令parent[x] = x。
對於查詢操作,假設需要確定x所在的的集合,也就是確定集合的代表元。可以沿著parent[x]不斷在樹形結構中向上移動,直到到達根節點。
判斷兩個元素是否屬於同一集合,只需要看他們的代表元是否相同即可。
為了加快查詢速度,查詢時將x到根節點路徑上的所有點的parent設為根節點,該優化方法稱為壓縮路徑。
使用該優化後,平均複雜度可視為ackerman函式的反函式,實際應用中可粗略認為其是乙個常數。
1、維護無向圖的連通性。支援判斷兩個點是否在同一連通塊內,和判斷增加一條邊是否會產生環。
(不理解)
2、用在求解最小生成樹的kruskal演算法裡。
《acm國際大學生程式設計競賽 知識與入門 俞勇主編》
一般來說,乙個並查集一三個操作。
有的人是建立乙個結構體把集合表示出來,如:
#define max 10000
struct node
node
[max];
有的人則是弄很多相同大小的陣列,如:
int
set[max];//集合index的類別,或者用parent表示
intrank[max];//集合index的層次,通常初始化為0
int data[max];//集合index的資料型別
//初始化集合
void make_set(int i)
一般來說,題目簡單用陣列,題目複雜用結構體,因為結構體有條理,陣列可以少打幾個字。
/**
*查詢集合i(乙個元素是乙個集合)的源頭(遞迴實現)。
如果集合i的父親是自己,說明自己就是源頭,返回自己的標號;
否則查詢集合i的父親的源頭。
**/int get_parent(int x)
陣列的話就是:
//查詢集合i(乙個元素是乙個集合)的源頭(遞迴實現)
intfind_set
(int i)
這就是所謂並查集的並了。至於怎麼知道兩個集合是可以合併的,那就是題目的條件了。
先看**:
void union(int a,int b)
}
再給出陣列顯示的合併函式:
void
union
(int i,int j)
}
簡單並查集
哈爾濱理工大學oj 1160 吸血鬼 description remilia是 東方紅魔館 中首次亮相的吸血鬼角色,是有著500歲年齡的吸血鬼領主。作為紅魔館的主人,有著高貴和威嚴的氣質,不過也經常任性和孩子氣。關於吸血鬼有很多傳說。吸血鬼是乙個血族,有著嚴格的等級。吸血鬼會嚴格聽從血之主人的命令。...
並查集演算法的描述
1 概念 在一些有n個元素的集合應用問題中,我們通常是在開始時讓每個元素構成乙個單元素的集合,然後按一定順序將屬於同一組的元素所在的集合合併,其間要反覆查詢乙個元素在哪個集合中。這一類問題近幾年來反覆出現在資訊學的國際國內賽題中,其特點是看似並不複雜,但資料量極大,若用正常的資料結構來描述的話,往往...
並查集 並查集
本文參考了 挑戰程式設計競賽 和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 ...