[백준 1647] 도시 분할 계획(Java)

최민길(Gale)·2024년 3월 22일
1

알고리즘

목록 보기
172/172

문제 링크 : https://www.acmicpc.net/problem/1647

이 문제는 최소 스패닝 트리를 이용하여 풀 수 있습니다. 마을을 두 개로 나누고 최소의 길을 유지하기 위해서는 다음의 과정을 거칩니다.

  1. 마을 전체를 최소의 길을 유지한 상태로 길을 제거한다
  2. 그 중에서 가장 코스트가 큰 하나의 길만을 제거한다

이 과정을 통해 최소의 길을 가진 마을 두 개로 나눌 수 있습니다. 1번 과정의 경우 최소 스패닝 트리를 구하면 해결할 수 있고, 2번의 경우 최소 스패닝 트리 특성 상 가장 마지막에 추가되는 노드가 가중치가 가장 큰 노드이기 때문에 가장 마지막 가중치를 최소 스패닝 트리의 총 간선 합에서 빼주면 됩니다.

다음은 코드입니다.

import java.util.*;
import java.io.*;

class Main{
    static int N,M;
    static int[] parent;
    static PriorityQueue<Node> queue = new PriorityQueue<>();

    public static void main(String[] args) throws Exception{
        init();

        int useNum = 0;
        int result = 0;
        int maxCost = 0;
        while(useNum < N-1){
            Node curr = queue.poll();

            if(find(curr.s) != find(curr.f)){
                union(curr.s, curr.f);
                result += curr.w;
                useNum++;
                maxCost = curr.w;
            }
        }
        System.out.println(result-maxCost);
    }

    static void union(int a, int b){
        a = find(a);
        b = find(b);
        if(a != b) parent[b] = a;
    }

    static int find(int a){
        if(a != parent[a]) return parent[a] = find(parent[a]);
        else return parent[a];
    }

    static void init() throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        parent = new int[N+1];
        for(int i=1;i<=N;i++) parent[i] = i;

        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());
            queue.add(new Node(a,b,c));
        }
    }

    static class Node implements Comparable<Node>{
        int s;
        int f;
        int w;

        Node(int s, int f, int w){
            this.s = s;
            this.f = f;
            this.w = w;
        }

        @Override
        public int compareTo(Node o){
            return this.w - o.w;
        }
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글

관련 채용 정보