-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWeightedUnionFind.java
More file actions
80 lines (65 loc) · 1.91 KB
/
WeightedUnionFind.java
File metadata and controls
80 lines (65 loc) · 1.91 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
71
72
73
74
75
76
77
78
79
80
/**
* @author ei1710
* @version 1.02
*/
//package toyama.ei1710.DataStructures;
import java.util.Arrays;
/**
* 重み付きUnionFind木.
* アーベル群まで拡張したいけどパフォが気になるので保留
* ArrayList\<Integer\>がint[]よりだいぶ遅い
* @see <a href="https://atcoder.jp/contests/arc090/submissions/5441773">検証1</a>
* @see <a href="http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3579461#1">検証2</a>
*/
public class WeightedUnionFind {
/** 親を示す 自身が根の場合は -(集合の大きさ) を持つ */
private int[] parent;
/** ノードの重み (親との差分) */
private int[] diff_weight;
public WeightedUnionFind(int nmemb) {
parent = new int[nmemb];
diff_weight = new int[nmemb];
Arrays.fill(parent, -1);
Arrays.fill(diff_weight, 0);
}
/** 根を求める */
private int root(int x) {
if (parent[x] < 0) {
return x;
}
// 累積和的に重みを再計算
int r = root(parent[x]);
diff_weight[x] += diff_weight[parent[x]];
parent[x] = r;
return parent[x];
}
private int weight(int x) {
root(x);
return diff_weight[x];
}
public int diff(int x, int y) {
return weight(y) - weight(x);
}
public boolean isSameGroup(int x, int y) {
return root(x) == root(y);
}
/**
* x->yの重みをwとして併合.
* 即ち, weight(y) = weight(x) + w が成り立つ
* x, yが既に同じグループのときは何もしない
*/
public void unite(int x, int y, int w) {
if (isSameGroup(x, y)) {
return;
}
w += weight(x);
w -= weight(y);
x = root(x);
y = root(y);
parent[y] = x;
diff_weight[y] = w;
}
public int groubSize(int x) {
return -parent[root(x)];
}
}