반응형
개인적인 풀이일 뿐, 최적의 정답이 아님을 알려드립니다.
문제
https://www.acmicpc.net/problem/10423
난이도: 골드 2
사용언어: JAVA
풀이
크루스칼 알고리즘을 사용하는 최소 스패닝 트리 문제입니다. 전형적인 최소 스패닝 트리 문제에 각각의 발전소와의 연결 여부만 추가적으로 확인해 주면 정답을 받을 수 있습니다.
각 발전소와의 연결 여부는 각 발전소의 부모와 해당 도시의 부모를 비교해보면 쉽게 구할 수 있겠죠?
참고로 각 발전소와의 연결 유무를 확인할 때 2중 반복문을 이용하면 시간 초과가 뜨게 되니 유의하셔야 합니다.
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
98
99
100
101
|
import java.io.*;
import java.util.*;
class Main {
static class node implements Comparable<node> {
int a;
int b;
int c;
node(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
public int compareTo(node o) {
return this.c - o.c;
}
}
static PriorityQueue<node> pq = new PriorityQueue<>();
static int[] parent;
static int[] root;
static int find(int x) {
if (parent[x] == x) {
return x;
}
parent[x] = find(parent[x]);
return parent[x];
}
static void union(int a, int b) {
parent[find(a)] = find(b);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
parent = new int[N + 1]; // 부모 배열
root = new int[K]; // 발전소의 번호 배열
for (int i = 0; i < N + 1; i++) {
parent[i] = i; // 부모 배열 초기화
}
st = new StringTokenizer(br.readLine());
for (int i = 0; i < K; i++) {
root[i] = Integer.parseInt(st.nextToken());
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
pq.add(new node(a, b, c));
}
int sum = 0; // 총 비용
while (!pq.isEmpty()) {
node nd = pq.poll(); // 편의상 연결할 두 도시를 1번 도시와 2번 도시로 호칭
int a = find(nd.a); // 1번 도시의 부모 업데이트
int b = find(nd.b); // 2번 도시의 부모 업데이트
if (a == b) { // 연결하고자 하는 두 도시가 이미 연결되어 있는지 체크
continue;
}
int flag1 = 0;
int flag2 = 0;
for (int i = 0; i < K; i++) { // 각 발전소들과 연결하고자 하는 도시가 연결되어 있는 지 여부
if (find(root[i]) == a) // 1번 도시와의 각 발전소 연결 여부
flag1 = 1;
if (find(root[i]) == b) // 2번 도시와의 각 발전소 연결 여부
flag2 = 1;
}
if (flag1 == 1 && flag2 == 1) // 둘 다 하나의 발전소라도 연결되어 있다면, 연결을 진행하지 않음
continue;
union(nd.a, nd.b); // 위에 모두 해당하지 않는다면 두 도시를 연결
sum += nd.c; // 총 비용에 연결 비용 추가
}
bw.write(String.valueOf(sum));
bw.flush();
br.close();
bw.close();
}
}
|
cs |
반응형
'백준 온라인 저지 > Gold' 카테고리의 다른 글
[BOJ] 3078 - 좋은 친구 (0) | 2022.02.03 |
---|---|
[BOJ] 2116 - 주사위 쌓기 (0) | 2022.01.31 |
[BOJ] 20058 - 마법사 상어와 파이어스톰 (1) | 2021.10.06 |
[BOJ] 16174 - 점프왕 쩰리 (Large) (0) | 2021.05.13 |
[BOJ] 1261 - 알고스팟 (1) | 2021.04.22 |