Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 카카오인턴
- c++
- LIS #Algorithm #요소추적
- 유니온파인드
- BaekJoon
- 투포인터
- 백준
- Union-find
- BFS
- 삼성 #코테 #2020상반기 #c++
- 소감
- Algorithm
- 카카오
- 알고리즘
- 식단
- 코테
- 중반부
- 서버개발캠프
- Smilegate
- 보석쇼핑
- IBK기업은행 #기업은행 #디지털 #직무 #정리
- 1편
- 스마일게이트
- 코딩테스트
Archives
- Today
- Total
짱아의 개발 기록장
백준 17398번. 통신망 분할(c++) / union-find 본문
반응형
이 문제는 처음에 딱 읽었을 때 bfs로 풀면 간단하겠다라고 생각했지만, 통신탑과 간선의 개수가 각각 최대 100,000 인것을 보고
bfs로 풀다가는 백퍼 시간초과가 나겠구나 싶었다.
그리고 다른 방법을 고민하다가 도저히 아이디어가 생각나지 않아, 문제 유형을 검색해보니
바로 "유니온파인드"를 이용하는 문제였다.
끊을 간선을 제외한 모든 간선을 먼저 연결해주고 끊을 간선들을 역순으로 하나씩 연결해주며
값을 계산해나가면 된다.
예를 들어, a->b a를 b와 연결해준다면 a의 부모 노드를 찾고 b의 부모노드를 찾아서 연결해주고
b의 부모노드의 값에 a의 부모노드의 값을 더해주면 된다. (cost[b] += cost[a] 이런식으로 구현했다.)
코드 첨부
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
|
// 통신망 분할 (union-find)
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int n, m, q, x, y, z;
vector<int> disconnect; // 끊을 곳
vector<pair<int, int>> v;
map<int, int> M;
int connect[100001] = {0, };
long long cost[100001] = {0, };
long long total = 0;
int find(int a){
if(a==connect[a]){
return a;
}else{
return connect[a] = find(connect[a]);
}
}
int main()
{
cin>>n>>m>>q;
for(int i=1; i<=m; i++){
cin>>x>>y;
v.push_back(make_pair(x, y));
}
for(int i=0; i<q; i++){
cin>>z;
M[z] = 1;
disconnect.push_back(z); // z번째 연결 요소를 끊는다.
}
for(int i=1; i<=n; i++){
cost[i] = 1;
connect[i] = i;
}
for(int i=0; i<v.size(); i++){
if(M[i+1]==1){ // 끊어야 할 연결요소
continue;
}
int a = find(v[i].first);
int b = find(v[i].second);
if(a!=b){
// a->b
connect[a] = b;
cost[b] += cost[a];
}
}
// 거꾸로 연결해준다.
for(int i=disconnect.size()-1; i>=0; i--){
int idx = disconnect[i]-1;
int a = find(v[idx].first);
int b = find(v[idx].second);
if(a!=b){
connect[a] = b;
total += cost[a]*cost[b];
cost[b] += cost[a];
}
}
cout<<total<<"\n";
return 0;
}
|
cs |
문제 첨부
https://www.acmicpc.net/problem/17398
반응형
'Algorithm > Baekjoon' 카테고리의 다른 글
백준 1701번. Cubeditor(c++) / kmp (0) | 2020.07.27 |
---|---|
백준 1593번. 문자 해독(c++) / 문자열 처리 (0) | 2020.07.24 |
백준 1890번. 점프(c++) / DP (0) | 2020.07.22 |
백준 16472번. 고냥이(c++) / 투포인터 (0) | 2020.07.22 |
[Algorithm] LIS 요소 역추적하기(backtracing) (0) | 2020.07.10 |
Comments