Skip to content

Commit eff769b

Browse files
authored
Merge pull request NASU41#18 from shojin-pro/#13_DSU
issue By NASU41#13 DSU, 2020/09/09
2 parents d0d6acf + da8ef15 commit eff769b

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

DSU/DSU.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
class DSU{
2+
private int n;
3+
private int[] parentOrSize;
4+
5+
public DSU(int n){
6+
this.n = n;
7+
this.parentOrSize = new int[n];
8+
Arrays.fill(parentOrSize,-1);
9+
}
10+
11+
int merge(int a, int b){
12+
if(!(0 <= a && a < n) || !(0 <= b && b < n)){
13+
// この式が成立しない物は動作しません。
14+
return -1;
15+
}
16+
int x = leader(a);
17+
int y = leader(b);
18+
if(x == y) return x;
19+
if(-parentOrSize[x] < -parentOrSize[y]){
20+
int tmp = x;
21+
x = y;
22+
y = tmp;
23+
}
24+
parentOrSize[x] += parentOrSize[y];
25+
parentOrSize[y] = x;
26+
return x;
27+
}
28+
29+
boolean same(int a, int b){
30+
if(!(0 <= a && a < n) || !(0 <= b && b < n)){
31+
// この式が成立しない物は動作しません。
32+
return false;
33+
}
34+
return leader(a) == leader(b);
35+
}
36+
37+
int leader(int a){
38+
if (parentOrSize[a] < 0){
39+
return a;
40+
}else{
41+
parentOrSize[a] = leader(parentOrSize[a]);
42+
return parentOrSize[a];
43+
}
44+
}
45+
46+
int size(int a) {
47+
if(!(0 <= a && a < n)){
48+
// この式が成立しない物は動作しません。
49+
return -1;
50+
}
51+
return -parentOrSize[leader(a)];
52+
}
53+
54+
ArrayList<ArrayList<Integer>> groups(){
55+
int[] leaderBuf = new int[n];
56+
int[] groupSize = new int[n];
57+
for(int i = 0; i < n; i++){
58+
leaderBuf[i] = leader(i);
59+
groupSize[leaderBuf[i]]++;
60+
}
61+
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
62+
for(int i = 0; i < n; i++){
63+
result.add(new ArrayList<>());
64+
}
65+
for(int i = 0; i < n; i++){
66+
result.get(leaderBuf[i]).add(i);
67+
}
68+
return result;
69+
}
70+
}

DSU/README.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# クラス DSU
2+
- - -
3+
4+
無向グラフに対して,
5+
6+
* 辺の追加
7+
* 2 頂点が連結かの判定
8+
9+
を $O(α(N))$ 時間で処理することが出来ます。
10+
11+
また、内部的に各連結成分ごとに代表となる頂点を 11 つ持っています。辺の追加により連結成分がマージされる時、新たな代表元は元の連結成分の代表元のうちどちらかになります。
12+
13+
## コンストラクタ
14+
### DSU
15+
```java
16+
public DSU(int n){
17+
```
18+
19+
* $n$頂点$0$辺の無向グラフを作ります。
20+
21+
制約
22+
頂点数 $n$ の配列 $a_0, a_1, \dots, a_{n-1}$を作ります.
23+
初期値はすべて-1です.
24+
(C++版だと10^8まで可能と書いてありますが、Javaだと厳しいかもしれません)
25+
計算量: $O(n)$
26+
27+
## メソッド
28+
### merge
29+
```java
30+
int merge(int a, int b)
31+
```
32+
辺$(a,b)$を足します。
33+
$a,b$ が連結だった場合はその代表元、非連結だった場合は新たな代表元を返します。(index外の数字を入れた場合は-1を返します。)
34+
**制約**
35+
* 0 \leq a < n
36+
* 0 \leq b < n
37+
38+
**計算量**
39+
* ならし$O(α(n))$
40+
41+
### same
42+
```java
43+
boolean same(int a, int b){
44+
```
45+
頂点$a,b$が連結かどうかを返します。
46+
47+
**制約**
48+
* 0 \leq a < n
49+
* 0 \leq b < n
50+
51+
**計算量**
52+
* ならし$O(α(n))$
53+
54+
### leader
55+
```java
56+
int leader(int a){
57+
```
58+
頂点$a$の属する連結成分の代表元を返します。
59+
60+
**制約**
61+
* 0 \leq a < n
62+
63+
**計算量**
64+
* ならし$O(α(n))$
65+
66+
### size
67+
```java
68+
int size(int a) {
69+
```
70+
頂点$a$の属する連結成分のサイズを返します。
71+
72+
**制約**
73+
* 0 \leq a < n
74+
75+
**計算量**
76+
* ならし$O(α(n))$
77+
78+
### groups
79+
```java
80+
ArrayList<ArrayList<Integer>> groups(){
81+
```
82+
グラフを連結成分に分け、その情報を返します。
83+
返り値は「「一つの連結成分の頂点番号のリスト」のリスト」です。 (内側外側限らず)vector内でどの順番で頂点が格納されているかは未定義です。
84+
85+
**計算量**
86+
* $O(n)$
87+
88+
## 使用例
89+
- Java11
90+
[[https://atcoder.jp/contests/practice2/submissions/16582269]]
91+
- Java8
92+
[[https://atcoder.jp/contests/practice2/submissions/16582277]]

0 commit comments

Comments
 (0)