반응형
알고리즘 종류
- MST
사고 과정
- 간선은 오르막길과 내리막길 뿐이기 때문에 비용을 계산하기 쉽게 오르막길은 1, 내리막길은 0으로 설정한다.
- 간선을 오름차순과 내림차순으로 정렬해서 각각 MST 알고리즘을 적용한다.
- 두 경우에서 나온 합을 이용해서 피로도 차이를 계산한다. 본인은 오르막길 비용을 1로 했기 때문에 오르막길의 개수^2은 피도로가 나온다.
구현(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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int N, M;
int worstSum = 0;
int bestSum = 0;
vector<pair<pair<int, int>, int> > edges;
int parents[1001];
bool cmp_increase(pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){
return a.second < b.second;
}
bool cmp_decrease(pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){
return a.second > b.second;
}
int getParent(int x){
if(parents[x] == x) return x;
return parents[x] = getParent(parents[x]);
}
void unionParents(int a, int b){
a = getParent(a);
b = getParent(b);
if(a > b) parents[b] = a;
else parents[a] = b;
}
void solution(){
// best
// 최고의 경우, 간선을 오름차순으로 정렬했을 때
sort(edges.begin(), edges.end(), cmp_increase);
for(int i=0; i<=N; i++) parents[i] = i;
for(int i=0; i<edges.size(); i++){
if(getParent(edges[i].first.first) != getParent(edges[i].first.second)){
bestSum += edges[i].second;
unionParents(edges[i].first.first , edges[i].first.second);
}
}
// worst
// 최악의 경우, 간선을 내림차순으로 정렬했을 때
sort(edges.begin(), edges.end(), cmp_decrease);
for(int i=0; i<=N; i++) parents[i] = i;
for(int i=0; i<edges.size(); i++){
if(getParent(edges[i].first.first) != getParent(edges[i].first.second)){
worstSum += edges[i].second;
unionParents(edges[i].first.first , edges[i].first.second);
}
}
// 2를 제곱해서 차를 출력
cout << pow(worstSum, 2) - pow(bestSum, 2);
}
int main(void){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> N >> M;
int A, B, C;
cin >> A >> B >> C;
// 입구에서 첫 건물까지 오르막이면 +1, 아니면 +0
if(C==0){
worstSum += 1;
bestSum += 1;
}
else{
worstSum += 0;
bestSum += 0;
}
for(int i=0; i<M; i++){
cin >> A >> B >> C;
if(C==0) edges.push_back({{A, B}, 1});
else edges.push_back({{A, B}, 0});
}
solution();
}
|
cs |
시행착오
반응형
'코딩 공부 > 백준' 카테고리의 다른 글
[백준][C++] 2933 미네랄 (0) | 2021.03.01 |
---|---|
[백준][C++] 13459 구슬 탈출 (0) | 2021.03.01 |
[백준][C++] 전기가 부족해 (0) | 2021.02.28 |
[백준][C++] 2352 반도체 설계 (0) | 2021.02.27 |
[백준][C++] 2467 용액 (0) | 2021.02.27 |