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;
	}
}

 

+ Recent posts