ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 2887 - JAVA] 행성터널
    Algorithm 2020. 11. 9. 18:09
    반응형
     

    2887번: 행성 터널

    첫째 줄에 행성의 개수 N이 주어진다. (1 ≤ N ≤ 100,000) 다음 N개 줄에는 각 행성의 x, y, z좌표가 주어진다. 좌표는 -109보다 크거나 같고, 109보다 작거나 같은 정수이다. 한 위치에 행성이 두 개 이

    www.acmicpc.net

    모든 행성을 터널로 연결하는데 필요한 최소 비용을 출력한다!

    간선을 찾고 MST로 연결하는 것은 쉽지만,

    행성의 개수가 100,000개로 시간초과 혹은 메모리 초과가 발생하는 문제다.

    나같은 경우에도 메모리 초과를 3번 겪고난 후 다른 블로그를 참고하여 문제를 해결했다.

     

     

    풀이 방법

    1. 각 행성의 Index와 x, y, z를 저장하고 Union-Find에서 사용할 배열을 초기화한다.
    2. 행성들의 거리를 계산하여 간선으로 PQ에 삽입한다.

      2-1. 모든 간선을 삽입할 경우 시간초과, 메모리 초과가 발생한다.

      2-2. 간선을 최소화로 넣기 위하여 X, Y, Z 각각을 기준으로 정렬 후 가까운 행성끼리의 간선만을 삽입한다.

    3. 크루스칼 알고리즘을 사용하여 최소 신장 부분 그래프를 완성한다.

     

     

     

    import java.io.*;
    import java.util.*;
    
    public class Main {
    	public static class Planet {
    		int idx;
    		int x, y, z;
    		public Planet(int idx, int x, int y, int z) {
    			this.idx = idx;
    			this.x = x;
    			this.y = y;
    			this.z = z;
    		}
    	}
    	
    	public static int N;
    	public static int ans;
    	public static int[] p;
    	public static Planet[] planets;
    	public static PriorityQueue<int[]> pq;
    	
    	public static void union(int x, int y) {
    		p[findSet(y)] = p[findSet(x)];
    	}
    	public static int findSet(int x) {
    		if (p[x] == x) return x;
    		return p[x] = findSet(p[x]);
    	}
    	
    	public static void main(String[] args) throws Exception {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		StringTokenizer st;
    		pq = new PriorityQueue<int[]>(new Comparator<int[]>() {
    			@Override
    			public int compare(int[] o1, int[] o2) {
    				return Integer.compare(o1[2], o2[2]);
    			}
    		});
    		N = Integer.parseInt(br.readLine());
    		planets = new Planet[N];
    		p = new int[N];
    		for (int i = 0; i < N; i++) {
    			st = new StringTokenizer(br.readLine());
    			int x = Integer.parseInt(st.nextToken());
    			int y = Integer.parseInt(st.nextToken());
    			int z = Integer.parseInt(st.nextToken());
    			planets[i] = new Planet(i, x, y, z);
    			p[i] = i;
    		}
    		
    		createEdge();
    		int cnt = 0;
    		while(!pq.isEmpty()) {
    			int[] cur = pq.poll();
    			if (findSet(cur[0]) != findSet(cur[1])){
    				ans+=cur[2];
    				if (++cnt == N-1) break;
    				union(cur[0], cur[1]);
    			}
    		}
    		
    		System.out.println(ans);
    	}
    	
    	public static void createEdge() {
    		Arrays.sort(planets, new Comparator<Planet>() {
    			@Override
    			public int compare(Planet o1, Planet o2) {
    				return Integer.compare(o1.x, o2.x);
    			}
    		});
    		for (int i = 1; i < N; i++) {
    			int dis = Math.abs(planets[i].x-planets[i-1].x);
    			pq.add(new int[] {planets[i].idx, planets[i-1].idx, dis});
    		}
    		
    		Arrays.sort(planets, new Comparator<Planet>() {
    			@Override
    			public int compare(Planet o1, Planet o2) {
    				return Integer.compare(o1.y, o2.y);
    			}
    		});
    		for (int i = 1; i < N; i++) {
    			int dis = Math.abs(planets[i].y-planets[i-1].y);
    			pq.add(new int[] {planets[i].idx, planets[i-1].idx, dis});
    		}
    		
    		Arrays.sort(planets, new Comparator<Planet>() {
    			@Override
    			public int compare(Planet o1, Planet o2) {
    				return Integer.compare(o1.z, o2.z);
    			}
    		});
    		for (int i = 1; i < N; i++) {
    			int dis = Math.abs(planets[i].z-planets[i-1].z);
    			pq.add(new int[] {planets[i].idx, planets[i-1].idx, dis});
    		}
    	}
    }
    

    'Algorithm' 카테고리의 다른 글

    [백준 1726 - JAVA] 로봇  (0) 2020.11.09
    [백준 9019 - JAVA] DSLR  (0) 2020.11.09
    [SWEA 4727 - JAVA] 견우와 직녀  (0) 2020.11.09
    [백준 3055 - JAVA] 탈출  (0) 2020.11.09
    [백준 2636 - JAVA] 치즈  (0) 2020.11.09

    댓글