코딩 공부/백준

[백준][C++] 1368 물대기

김 정 환 2021. 4. 11. 11:15
반응형

www.acmicpc.net/problem/1368

 

1368번: 물대기

첫 줄에는 논의 수 N(1 ≤ N ≤ 300)이 주어진다. 다음 N개의 줄에는 i번째 논에 우물을 팔 때 드는 비용 Wi(1 ≤ Wi ≤ 100,000)가 순서대로 들어온다. 다음 N개의 줄에 대해서는 각 줄에 N개의 수가 들어

www.acmicpc.net

 

 

 

알고리즘 종류

MST

크루스칼

 

 

사고 과정

'논 사이 연결 VS 논에 우물파기'를 비교해야 하는 문제입니다. 생각해보면, 트리가 여러 개 나올 수 있다는 것을 알 수 있습니다. 이럴 경우, 가상의 노드를 생성하여 해결할 수 있습니다. 즉, 가상의 노드 0을 만들고 0과 연결된 간선을 우물을 파는 비용으로 하면 됩니다. 아래 그림으로 설명해드리겠습니다.

 

우선 초기 상태입니다. 붉은색은 우물을 파는 비용, 주황색은 논을 연결하는 비용입니다.

 

이제 가상의 노드 0으로 연결하겠습니다. 우물을 파는 비용인 붉은색은 그대로 0번과 연결된 간선의 비용이 됩니다. 이제 일반전인 MST 알고리즘을 적용하면 됩니다.

 

이렇게 가상의 노드를 만드는 방법과 유사한 문제가 있습니다. 이것입니다. 알고리즘 유형은 최단경로이지만 마찬가지로 가상의 노드를 만들어서 문제를 해결합니다.

 

 

 

구현(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
#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
int n;
 
int mat[301][301];
int parents[301];
vector<pair<intpair<intint> > > edges;
 
 
bool cmp(pair<intpair<intint> > a,  pair<intpair<intint> > b){
    return a.first < b.first;
}
 
 
int get_parent(int a){
    if(parents[a] == a) return a;
    return parents[a] = get_parent(parents[a]);
}
 
 
void union_parents(int a, int b){
    a = get_parent(a);
    b = get_parent(b);
    
    if(a > b) parents[a] = b;
    else parents[b] = a;
}
 
 
void solution(){
    
    sort(edges.begin(), edges.end(), cmp);
    for(int i=0; i<=n; i++) parents[i] = i;
    
    int sum = 0;
    for(int i=0; i<edges.size(); i++){
        int node1 = edges[i].second.first;
        int node2 = edges[i].second.second;
        int cost = edges[i].first;
        
        if(get_parent(node1) != get_parent(node2)){
            union_parents(node1, node2);
            sum += cost;
        }
    }
    
    cout << sum << endl;
}
 
 
int main(void){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    
    cin >> n;
    
    int cost;
    for(int i=1; i<=n; i++){
        cin >> cost;
        edges.push_back({cost, {0, i}});
    }
        
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            cin >> mat[i][j];
        }
    }
    
    for(int i=1; i<=n; i++){
        for(int j=i+1; j<=n; j++){
            edges.push_back({mat[i][j], {i, j}});
        }
    }
    
    solution();
}
cs

 

 

 

시행착오

반응형

'코딩 공부 > 백준' 카테고리의 다른 글

[백준][C++] 3190 뱀  (0) 2021.04.11
[백준][C++] 1414 불우이웃돕기  (0) 2021.04.11
[백준][C++] 12100 2048 (Easy)  (0) 2021.04.10
[백준][C++] 13460 구슬 탈출 2  (0) 2021.04.10
[백준][C++] 1445 일요일 아침의 데이트  (0) 2021.04.10