코딩 공부/백준

[백준][C++] 13418 학교 탐방하기

김 정 환 2021. 2. 28. 15:51
반응형

www.acmicpc.net/problem/13418

 

13418번: 학교 탐방하기

입력 데이터는 표준 입력을 사용한다. 입력은 1개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 건물의 개수 N(1≤N≤1,000)과 도로의 개수 M(1≤M≤n*(n-1)/2) 이 주어진다. 입력의 두 번째 줄

www.acmicpc.net

 

 

 

알고리즘 종류

    - 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<intint>int> > edges;
int parents[1001];
 
 
bool cmp_increase(pair<pair<intint>int> a, pair<pair<intint>int> b){
    return a.second < b.second;
}
 
bool cmp_decrease(pair<pair<intint>int> a, pair<pair<intint>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