map을 이용하여 입력으로 이름이 들어오는 순서대로 인덱스를 부여합니다.
만약 이미 인덱스가 부여된 이름이라면 map에 저장된 인덱스를 가져옵니다.
이제 두 친구의 인덱스가 생겼으니 union-find로 둘을 이어줍니다.
이 때 Union 함수에서 a와 b가 다를때만 친구 네트워크 수를 b만큼 a에 더해줍니다.
[C++]
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
|
#include <iostream>
#include <string>
#include <map>
using namespace std;
map<string, int> m;
int parent[200001];
int friends[200001];
int N, idx;
int find(int v) {
if (parent[v] == v) return v;
return parent[v] = find(parent[v]);
}
void Union(int x, int y) {
int a = find(x);
int b = find(y);
if (a != b) {
parent[b] = a;
friends[a] += friends[b];
}
}
void input() {
string str1, str2;
int u, v;
cin >> N;
for (int i = 0; i < N; i++) {
cin >> str1 >> str2;
if (m.find(str1) == m.end()) {
m.insert({ str1, idx });
parent[idx] = idx;
friends[idx] = 1;
u = idx++;
}
else {
u = m[str1];
}
if (m.find(str2) == m.end()) {
m.insert({ str2, idx });
parent[idx] = idx;
friends[idx] = 1;
v = idx++;
}
else {
v = m[str2];
}
Union(u, v);
cout << friends[find(u)] << '\n';
}
}
int main() {
cin.tie(NULL); cout.tie(NULL);
ios::sync_with_stdio(false);
int tc;
cin >> tc;
while (tc--) {
input();
m.clear();
idx = 0;
}
return 0;
}
|
cs |
[Java]
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
81
82
83
84
85
|
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static StringBuffer sb = new StringBuffer();
static Map<String, Integer> m = new HashMap<>();
static int parent[][] = new int[200001][2];
static int N, idx = 1;
static int find(int v) {
if (parent[v][0] == v)
return parent[v][0];
return parent[v][0] = find(parent[v][0]);
}
static void union(int u, int v) {
int a = find(u);
int b = find(v);
if (a != b) {
parent[a][1] += parent[b][1];
parent[b][0] = parent[a][0];
}
sb.append(parent[a][1]).append("\n");
}
static void init() {
for (int i = 1; i <= N * 2; i++) {
parent[i][0] = i;
parent[i][1] = 1;
}
}
static void input() throws Exception {
String str1, str2;
int u, v;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
init();
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
str1 = st.nextToken();
str2 = st.nextToken();
if (m.containsKey(str1))
u = m.get(str1);
else {
m.put(str1, idx);
u = idx++;
}
if (m.containsKey(str2))
v = m.get(str2);
else {
m.put(str2, idx);
v = idx++;
}
if (v < u) {
int tmp = u;
u = v;
v = tmp;
}
union(u, v);
}
}
public static void main(String[] args) throws Exception {
st = new StringTokenizer(br.readLine());
int tc = Integer.parseInt(st.nextToken());
while (tc-- > 0) {
input();
m.clear();
idx = 1;
}
System.out.println(sb.toString());
}
}
|
cs |
'algorithm > Union-Find' 카테고리의 다른 글
boj 20040 사이클 게임 (0) | 2021.06.27 |
---|---|
boj 1043 거짓말 (0) | 2021.04.05 |
boj 10775 공항 (0) | 2021.03.17 |
boj 1976 여행 가자 (0) | 2021.03.17 |
boj 1717 집합의 표현 (0) | 2021.02.06 |