알고리즘/BOJ 문제풀이

[MST] BOJ 10423 전기가 부족해

4Legs 2021. 1. 19. 21:37

문제 링크 : www.acmicpc.net/problem/10423

 

10423번: 전기가 부족해

첫째 줄에는 도시의 개수 N(1 ≤ N ≤ 1,000)과 설치 가능한 케이블의 수 M(1 ≤ M ≤ 100,000)개, 발전소의 개수 K(1 ≤ K ≤ N)개가 주어진다. 둘째 줄에는 발전소가 설치된 도시의 번호가 주어진다. 셋째

www.acmicpc.net

모든 도시에 전기가 공급되어야 하며, 한 도시가 둘 이상의 발전소에서 전기를 공급받지 않아야 한다는 점에서 MST를 구하는 문제로 접근할 수 있다.

둘 이상의 발전소에서 전기를 공급받지 않아야 한다는 것은 곧 사이클 없이 모든 정점을 잇는 것과 같기 때문이다.

단, 일반적인 MST 문제와의 차이는 아래의 예제와 같이 모든 정점이 서로 연결되어 있지는 않다는 점이다.

예제의 정답

 

이는 최초 발전기가 설치된 도시의 개수가 2개 이상이기 때문이다.

즉, 최초 발전기가 설치된 A, B, I 정점이 각각 트리의 root가 된다.

따라서 Prim 알고리즘을 통해, 최초 우선순위 큐에 제시된 발전소들의 간선을 모두 넣은 상태로 MST를 구한다.

 

[코드]

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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <queue>
 
using namespace std;
typedef pair<intint> p;
 
int n, m, k;
bool gen[1001], visit[1001];
vector<int> gens;
vector<p> adj[1001];
 
int prim() {
    int retval = 0, cnt = k;
    priority_queue<pair<intint>vector<pair<intint>>, greater<pair<intint>>> pque;
 
    for (int i = 0; i < gens.size(); i++) {
        int num = gens[i];
        for (int j = 0; j < adj[num].size(); j++) {
            pque.push(adj[num][j]);
        }
    }
 
    while (!pque.empty()) {
        p cur = pque.top();
        pque.pop();
 
        int dist = cur.first;
        int node = cur.second;
 
        if (visit[node]) continue;
        visit[node] = true;
        retval += dist;
        cnt++;
        if (cnt == n) break;
 
        for (int i = 0; i < adj[node].size(); i++) {
            int next = adj[node][i].second;
            if (visit[next]) continue;
            pque.push({ adj[node][i].first, next });
        }
 
    }
    return retval;
}
 
void init() {
    int g, f, s, w;
    cin >> n >> m >> k;
 
    for (int i = 0; i < k; i++) {
        cin >> g;
        gen[g] = true; visit[g] = true;
        gens.push_back(g);
    }
 
    for (int i = 0; i < m; i++) {
        cin >> f >> s >> w;
        adj[f].push_back({ w, s });
        adj[s].push_back({ w, f });
    }
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(NULL);
 
    init();
    int answer = prim();
    printf("%d\n", answer);
 
    return 0;
}
cs

'알고리즘 > BOJ 문제풀이' 카테고리의 다른 글

[Tree/DP] BOJ 2213 트리의 독립집합  (0) 2021.01.23
[Math] BOJ 8916 이진 검색 트리  (0) 2021.01.23
[Math] BOJ 1111 IQ Test  (0) 2021.01.18
[DP] BOJ 1086 박성원  (0) 2021.01.17
[DFS] BOJ 17501 수식 트리  (0) 2021.01.16