https://www.acmicpc.net/problem/16398
16398번: 행성 연결
홍익 제국의 중심은 행성 T이다. 제국의 황제 윤석이는 행성 T에서 제국을 효과적으로 통치하기 위해서, N개의 행성 간에 플로우를 설치하려고 한다. 두 행성 간에 플로우를 설치하면 제국의 함
www.acmicpc.net
코드설명
최소신장트리(Minimum Spanning Tree, MST) + 크루스칼(Kruskal)를 활용하는 문제입니다.
다만,
문제 조건에 보면
각 행성간의 플로우 관리 비용이 N x N 행렬 (Cij), (1 ≤ i, j ≤ N, 1 ≤ Cij ≤ 100,000,000, Cij = Cji, Cii = 0)
최악의 상황을 가정하면, 만약 N이 1000이고, 각 모든 비용이 100,000,000 이라면, 최소비용을 구한다고하였을때
1000 * 100,000,000 = 100,000,000,000(1000억) 입니다.
1000 억은 int 범위를 벗어나므로 long으로 선언합니다.
또한 시간을 줄일 수 있는 방법으로, 행렬에 대한 처리가 있습니다.
for(int i=1;i<=N;i++) {
st = new StringTokenizer(br.readLine());
for(int j=1;j<=i;j++) {
int cost = Integer.parseInt(st.nextToken());
if(i == j) continue;
edges.add(new Edge(i, j, cost));
}
}
위의 코드처럼 j<=i 까지 처리합니다. 처음에는 j<=N 까지 처리하여 같은 간선을 2번 처리했습니다.
코드
BufferedReader와 행렬상에서 최적화 진행한 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
public class Main {
public static int N;
public static int[] parent = new int[1001];
public static ArrayList<Edge> edges = new ArrayList<>();
public static long result = 0;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N= Integer.parseInt(st.nextToken());
for(int i=0;i<=N;i++) {
parent[i] = i;
}
for(int i=1;i<=N;i++) {
st = new StringTokenizer(br.readLine());
for(int j=1;j<=i;j++) {
int cost = Integer.parseInt(st.nextToken());
if(i == j) continue;
edges.add(new Edge(i, j, cost));
}
}
Collections.sort(edges);
for(int i=0;i<edges.size();i++) {
int a = edges.get(i).nodeA;
int b = edges.get(i).nodeB;
int cost = edges.get(i).distance;
if( findParent(a) != findParent(b) ) {
unionParent(a, b);
result += cost;
}
}
System.out.println(result);
}
//부모를 찾는다.
public static int findParent(int a) {
if( a == parent[a]) return a;
return parent[a] = findParent(parent[a]);
}
//
public static void unionParent(int a, int b) {
a = findParent(a);
b = findParent(b);
if( a < b ) parent[b] = a;
else parent[a] = b;
}
}
class Edge implements Comparable<Edge>{
int nodeA;
int nodeB;
int distance;
public Edge(int nodeA, int nodeB, int distance) {
this.nodeA = nodeA;
this.nodeB = nodeB;
this.distance = distance;
}
//비용이 낮은것으로 정렬합니다.
@Override
public int compareTo(Edge other) {
if(this.distance > other.distance) {
return 1;
}else if(this.distance < other.distance) {
return -1;
}
return 0;
}
}
import java.util.*;
public class Main {
public static int N;
public static int[] parent = new int[1001];
public static ArrayList<Edge> edges = new ArrayList<>();
public static long result = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N=sc.nextInt();
for(int i=0;i<=N;i++) {
parent[i] = i;
}
for(int i=1;i<=N;i++) {
for(int j=1;j<=N;j++) {
int cost = sc.nextInt();
if(i == j) continue;
edges.add(new Edge(i, j, cost));
}
}
Collections.sort(edges);
for(int i=0;i<edges.size();i++) {
int a = edges.get(i).nodeA;
int b = edges.get(i).nodeB;
int cost = edges.get(i).distance;
if( findParent(a) != findParent(b) ) {
unionParent(a, b);
result += cost;
}
}
System.out.println(result);
}
//부모를 찾는다.
public static int findParent(int a) {
if( a == parent[a]) return a;
return parent[a] = findParent(parent[a]);
}
//
public static void unionParent(int a, int b) {
a = findParent(a);
b = findParent(b);
if( a < b ) parent[b] = a;
else parent[a] = b;
}
}
class Edge implements Comparable<Edge>{
int nodeA;
int nodeB;
int distance;
public Edge(int nodeA, int nodeB, int distance) {
this.nodeA = nodeA;
this.nodeB = nodeB;
this.distance = distance;
}
//비용이 낮은것으로 정렬합니다.
@Override
public int compareTo(Edge other) {
if(this.distance > other.distance) {
return 1;
}else if(this.distance < other.distance) {
return -1;
}
return 0;
}
}