
전력난 문제는 여러 도시와 이들을 연결하는 도로들이 주어졌을 때,
모든 도시가 연결된 상태를 유지하면서 불필요한 도로의 전력 소비를 줄여
절약할 수 있는 전력의 총합을 구하는 문제입니다.
입력:
출력:
문제의 핵심은 모든 도시를 연결하는 상태를 유지하면서,
불필요한 도로의 전력 소비를 제거하는 것입니다.
즉, 전체 도로 비용에서 MST를 구성하는 데 사용된 도로 비용을 빼면
절약 가능한 전력의 양을 구할 수 있습니다.
아이디어:
allSum)과 MST 도로 비용(mstSum)을 각각 구합니다.  allSum - mstSum으로 계산됩니다.알고리즘 선택:
입력 처리 및 초기화:
allSum)을 누적합니다.최소 신장 트리(MST) 구성:
mstSum을 구합니다.절약 가능한 전력 계산:
allSum)에서 MST 구성 비용(mstSum)을 빼면,import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
    private static StringTokenizer st;
    private static StringBuilder sb = new StringBuilder();
    private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static int N, M;
    private static PriorityQueue<int[]> pq;
    private static int[] parent;
    private static int allSum;
    public static void main(String[] args) throws IOException {
        /*
         * 문제의 핵심은 모든 도시를 연결하는 상태를 유지하면서,
         * 불필요한 도로를 제거해 절약할 수 있는 전력의 총합을 구하는 것입니다.
         * 전체 도로 비용에서 MST 구성에 사용된 비용을 빼면,
         * 절약 가능한 전력의 양을 구할 수 있습니다.
         * 여기서는 Kruskal 알고리즘과 Union-Find 자료구조를 활용했습니다.
         */
        while (true) {
            if (!isSetting()) break;
            sb.append(allSum - getMstSum()).append("\n");
        }
        System.out.println(sb.toString());
    }
    private static int getMstSum() {
        int sum = 0;
        while (pq.size() > 0) {
            int[] cur = pq.poll();
            int from = cur[0];
            int to = cur[1];
            int val = cur[2];
            if (find(from) != find(to)) {
                union(from, to);
                sum += val;
            }
        }
        return sum;
    }
    private static int find(int num) {
        if (num == parent[num]) return num;
        return parent[num] = find(parent[num]);
    }
    private static void union(int num1, int num2) {
        int parent1 = find(num1);
        int parent2 = find(num2);
        if (parent1 < parent2) {
            parent[parent2] = parent1;
            find(num2); // 경로 압축을 통한 최적화
        } else {
            parent[parent1] = parent2;
            find(num1); // 경로 압축을 통한 최적화
        }
    }
    private static boolean isSetting() throws IOException {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        if (N == 0 && M == 0) return false; // 종료 조건
        parent = new int[N];
        for (int i = 0; i < N; i++) {
            parent[i] = i;
        }
        pq = new PriorityQueue<>(Comparator.comparingInt(o -> o[2]));
        allSum = 0;
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());
            int to = Integer.parseInt(st.nextToken());
            int val = Integer.parseInt(st.nextToken());
            allSum += val;
            pq.add(new int[]{from, to, val});
        }
        return true;
    }
}
입력 처리 및 초기화:
allSum)을 누적합니다.최소 신장 트리(MST) 구성:
mstSum을 구합니다.절약 가능한 전력 계산:
allSum)에서 MST 구성 비용(mstSum)을 빼면,