[SWEA] 4006. 고속도로 건설 2
Problem
제출일 : 2019-12-16
문제 풀이 시간 : 25M
난이도 : ★★
link : https://swexpertacademy.com/main/learn/course/subjectDetail.do?subjectId=AWWxyoNqAiQDFAW4
그러나 비싼 비용의 문제에 부딪혀, 정부는 최소 비용으로 모든 도시 간을 이동할 수 있게 하고 싶어한다.
또한 하나의 제약이 더 있는데, 언덕 등을 깎지 않는 친환경 건설을 위해 어떤 도시끼리는 직접 도로를 이을 수 없다.
친환경 건설을 위해 이을 수 있는 도로의 목록이 주어질 때, 정부를 도와 모든 도시 간을 잇는 고속도로를 건설하는 최소 비용을 알아내자.
input
첫 줄에 테스트케이스의 개수 T가 주어진다. (1 ≤ T ≤ 8)
각 테스트 케이스의 첫 번째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 50,000)
각 테스트 케이스의 두 번째 줄에 도로 후보의 수 M이 주어진다. (1 ≤ M ≤ 200,000)
각 테스트 케이스의 세 번째 줄부터 M개의 줄에 걸쳐 각 도로 후보의 정보 s, e, c가 주어진다.
s와 e는 도로 후보가 잇는 각 도시의 번호이고, c는 그 도로를 건설하는데 드는 비용이다. (1 ≤ c ≤ 10,000)
항상 모든 도시를 잇는 고속도로를 건설할 수 있는 입력만 주어진다.
Output
각 테스트케이스마다 한 줄에 걸쳐, 테스트케이스 수 “#(TC) “를 출력하고, 모든 도시를 잇는 고속도로를 건설하는데 드는 최소 비용을 출력한다.
Example
input
1
5
8
1 2 4
1 3 9
1 4 21
2 3 8
2 4 17
3 4 16
5 2 20
5 4 30
output
#1 48
Solution & Inpression
크루스칼 알고리즘을 이용하여 구현하였다.
시간 복잡도를 줄이기 위해 PriorityQueue를 이용하여 가장 적은 비용의 간선을 추출하고 Union-Find알고리즘을 이용 싸이클을 검사했다.
MST 알고리즘은 예전에 확실히 개념을 공부하고 기억하고 있어 쉽게 구현이 가능했다.
Code
언어 : JAVA
import java.io.FileInputStream;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Solution {
final static int MAX = 50009;
static PriorityQueue<Edge> pq;
static int parents[] = new int[MAX];
static int N, M, ans;
static class Edge implements Comparable<Edge> {
int start, end, cost;
public Edge(int start, int end, int cost) {
this.start = start;
this.end = end;
this.cost = cost;
}
@Override
public int compareTo(Edge o) {
return this.cost > o.cost ? 1 : -1;
}
}
public static void main(String[] args) throws Exception {
System.setIn(new FileInputStream("res/input.txt"));
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int tc = 1; tc <= T; tc++) {
N = sc.nextInt();
M = sc.nextInt();
pq = new PriorityQueue<>();
for (int i = 1; i <= M; i++) {
pq.add(new Edge(sc.nextInt(), sc.nextInt(), sc.nextInt()));
}
ans = 0;
makeSet();
while (!pq.isEmpty()) {
Edge e = pq.poll();
int x = find(e.start);
int y = find(e.end);
if (x == y)
continue;
else {
ans += e.cost;
union(x, y);
}
} // end of while
System.out.println("#" + tc + " " + ans);
}
}// end of main
private static void union(int x, int y) {
if (x > y)
parents[x] = parents[y];
else
parents[y] = parents[x];
}
private static int find(int x) {
if (x == parents[x])
return parents[x];
else
return x = find(parents[x]);
}
private static void makeSet() {
for (int i = 1; i <= N; i++) {
parents[i] = i;
}
}
}
'Problem > SWEA' 카테고리의 다른 글
[SWEA] 2819. 격자판의 숫자 이어 붙이기 (D4) (Java) (0) | 2020.02.18 |
---|---|
[SWEA] 1204. [S/W 문제해결 기본] 1일차 - 최빈수 구하기 (D2) (0) | 2020.01.12 |
[SWEA] 3813. 그래도 수명이 절반이 되어서는... (0) | 2019.12.13 |
[SWEA] 3816. 아나그램 (0) | 2019.12.11 |
[SWEA] 3819. 최대 부분 배열 (0) | 2019.12.10 |