並查集可以簡單的看作是對集合的「合併和查詢」。每乙個元素都唯一屬於乙個集合,每乙個集合都有唯一的乙個根元素,來唯一標識這個集合。如何儲存元素?
可以用陣列來儲存元素,陣列下標代表該元素,陣列的值代表該元素的父元素。例如father[a] = b。就代表a元素的父元素是b。
如何表示根元素?
規定一下,只要father[i] = i ,則代表i為該集合的根元素。
並查集的兩個基本操作就是查詢和合併。查詢:就是查詢該元素的父元素。合併:合併兩個集合,可以簡化為合併兩個集合的根節點。
查詢操作
int findfather(int a)
return a;
}
合併操作
void union(int a, int b)
}
並查集的兩種常見的問題是:1)求集合數 2)求每個集合中的元素個數
這兩種問題都可以通過乙個陣列來解決。
對於求集合數,可以開乙個布林型的陣列isroot,陣列的初始的值都為false。在進行完合併的操作之後。遍歷一下所有的元素的父元素,標記為true即可。
for
(int i=
1; i<=n; i++
)int ans =0;
for(
int i=
1; i<=n; i++
)//ans的值就位集合的個數
對於求每乙個集合中的元素個數,只需要將上面的isroot陣列的型別改為int型,初始化為0,然後在遍歷每乙個元素的父元素時累加即可。
for
(int i=
1; i<=n; i++
)//isroot[i] 的值代表以i為根節點的集合的元素的個數
並查集模板
#include
#include
using namespace std;
const
int maxn =
1010
;int n;
//人數
int father[maxn]
;int isroot[maxn]=;
//初始化
void
initialize
(int n)
}//查詢根元素
intfind_father
(int x)
//路徑壓縮
while
( a != father[a]
)return x;
}//合併
void
union
(int a,
int b)
}
並查集操作
並查集用來管理元素分組情況的資料結構。1.初始化集合。陣列fa記錄每個節點的父節點編號,初始時各元素單獨形成乙個集合,fa x x,x是所在樹的根。另設rank陣列記錄根節點的秩,可以是樹高度,也可以是集合內元素個數。void init int n 非遞迴方法 int find int x retu...
並查集 並查集的刪除操作
描述 一天小 w 給學弟們上課,小 w 說 注意了,並查集只適合於加的操作,不太方便處理減的操作喲。j 老師聽了後,呵呵了一下。她課後找到小 w 說,其實並查集也可以做減的操作的。只看你如何靈活運用了。比如這個題 給你 n 個元素,最開始時分屬於 n 個集合,有如下三種操作 小 w 陷入了無盡的思考...
並查集 並查集
本文參考了 挑戰程式設計競賽 和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 ...