-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUnionFind.java
More file actions
70 lines (60 loc) · 2.35 KB
/
Copy pathUnionFind.java
File metadata and controls
70 lines (60 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Shunta の自作ライブラリ
// https://github.com/NAVYSHUNTA/atcoder-shunta-library/blob/main/data_structure/Union-Find/java/UnionFind.java
// Union-Find 木クラス
class UnionFind {
private int[] leader;
private int[] groupSize;
private int groupCount;
UnionFind(int n) {
leader = new int[n];
groupSize = new int[n];
for (int i = 0; i < n; i++) {
leader[i] = -1;
groupSize[i] = 1;
groupCount = n;
}
}
// O(log N): v の根を返すメソッド
// 経路圧縮ありなら、ならし計算量 O(α(N)): v の根を返すメソッド
int root(int v) {
if (this.leader[v] == -1) {
return v;
} else {
// 経路圧縮を行わない場合:UnionFind の各操作は O(log N)
// return this.root(this.leader[v]);
// 経路圧縮を行う場合:UnionFind の各操作は、ならし計算量で O(α(N)) ここで α は逆アッカーマン関数
return this.leader[v] = this.root(this.leader[v]);
}
}
// O(log N): x と y が属するグループを併合するメソッド
// 経路圧縮ありなら、ならし計算量 O(α(N)): x と y が属するグループを併合するメソッド
void union(int x, int y) {
int lx = this.root(x);
int ly = this.root(y);
if (lx == ly) {
return;
}
if (this.groupSize[lx] < this.groupSize[ly]) {
int tmp = lx;
lx = ly;
ly = tmp;
}
this.leader[ly] = lx;
this.groupSize[lx] += this.groupSize[ly];
this.groupCount -= 1;
}
// O(log N): x と y が同じグループに属するかを返すメソッド
// 経路圧縮ありなら、ならし計算量 O(α(N)): x と y が同じグループに属するかを返すメソッド
boolean isSame(int x, int y) {
return this.root(x) == this.root(y);
}
// O(log N): v が属するグループのサイズを返すメソッド
// 経路圧縮ありなら、ならし計算量 O(α(N)): v が属するグループのサイズを返すメソッド
int getGroupSize(int v) {
return this.groupSize[this.root(v)];
}
// O(1): 連結成分の個数を返すメソッド
int getGroupCount() {
return this.groupCount;
}
}