[Programmers] ์„ฌ ์—ฐ๊ฒฐํ•˜๊ธฐ

๋ฌธ์ œ

๋ฌธ์ œ ์„ค๋ช…

Programmers - ์„ฌ ์—ฐ๊ฒฐํ•˜๊ธฐ

n๊ฐœ์˜ ์„ฌ ์‚ฌ์ด์— ๋‹ค๋ฆฌ๋ฅผ ๊ฑด์„คํ•˜๋Š” ๋น„์šฉ(costs)์ด ์ฃผ์–ด์งˆ ๋•Œ, ์ตœ์†Œ์˜ ๋น„์šฉ์œผ๋กœ ๋ชจ๋“  ์„ฌ์ด ์„œ๋กœ ํ†ตํ–‰ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค ๋•Œ ํ•„์š”ํ•œ ์ตœ์†Œ ๋น„์šฉ์„ return ํ•˜๋„๋ก solution์„ ์™„์„ฑํ•˜์„ธ์š”.

๋‹ค๋ฆฌ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ฑด๋„ˆ๋”๋ผ๋„, ๋„๋‹ฌํ•  ์ˆ˜๋งŒ ์žˆ์œผ๋ฉด ํ†ตํ–‰ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ๋ด…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด A ์„ฌ๊ณผ B ์„ฌ ์‚ฌ์ด์— ๋‹ค๋ฆฌ๊ฐ€ ์žˆ๊ณ , B ์„ฌ๊ณผ C ์„ฌ ์‚ฌ์ด์— ๋‹ค๋ฆฌ๊ฐ€ ์žˆ์œผ๋ฉด A ์„ฌ๊ณผ C ์„ฌ์€ ์„œ๋กœ ํ†ตํ–‰ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ž…๋ ฅ

n๊ฐœ์˜ ์„ฌ ์‚ฌ์ด์— ๋‹ค๋ฆฌ๋ฅผ ๊ฑด์„คํ•˜๋Š” ๋น„์šฉ(costs)

n costs
4 [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]]

์ถœ๋ ฅ

์ตœ์†Œ์˜ ๋น„์šฉ์œผ๋กœ ๋ชจ๋“  ์„ฌ์ด ์„œ๋กœ ํ†ตํ–‰ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค ๋•Œ ํ•„์š”ํ•œ ์ตœ์†Œ ๋น„์šฉ

์ œํ•œ

  • ์„ฌ์˜ ๊ฐœ์ˆ˜ n์€ 1 ์ด์ƒ 100 ์ดํ•˜์ž…๋‹ˆ๋‹ค.
  • costs์˜ ๊ธธ์ด๋Š” ((n-1) * n) / 2์ดํ•˜์ž…๋‹ˆ๋‹ค.
  • ์ž„์˜์˜ i์— ๋Œ€ํ•ด, costs[i][0] ์™€ costs[i] [1]์—๋Š” ๋‹ค๋ฆฌ๊ฐ€ ์—ฐ๊ฒฐ๋˜๋Š” ๋‘ ์„ฌ์˜ ๋ฒˆํ˜ธ๊ฐ€ ๋“ค์–ด์žˆ๊ณ , costs[i] [2]์—๋Š” ์ด ๋‘ ์„ฌ์„ ์—ฐ๊ฒฐํ•˜๋Š” ๋‹ค๋ฆฌ๋ฅผ ๊ฑด์„คํ•  ๋•Œ ๋“œ๋Š” ๋น„์šฉ์ž…๋‹ˆ๋‹ค.
  • ๊ฐ™์€ ์—ฐ๊ฒฐ์€ ๋‘ ๋ฒˆ ์ฃผ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ๋”๋ผ๋„ ๊ฐ™์€ ์—ฐ๊ฒฐ๋กœ ๋ด…๋‹ˆ๋‹ค. ์ฆ‰ 0๊ณผ 1 ์‚ฌ์ด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋น„์šฉ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, 1๊ณผ 0์˜ ๋น„์šฉ์ด ์ฃผ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ชจ๋“  ์„ฌ ์‚ฌ์ด์˜ ๋‹ค๋ฆฌ ๊ฑด์„ค ๋น„์šฉ์ด ์ฃผ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ๋‘ ์„ฌ ์‚ฌ์ด์˜ ๊ฑด์„ค์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ์œผ๋กœ ๋ด…๋‹ˆ๋‹ค.
  • ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†๋Š” ์„ฌ์€ ์ฃผ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ’€์ด

ํ•ด์„ค

์ตœ์†Œ์‹ ์žฅํŠธ๋ฆฌ(MST) ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ค‘ ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋Š” ํฌ๋ฃจ์Šค์นผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ’€์ด

๊ฐ„์„  ๊ฐ€์ค‘์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฐ„์„  ์ •๋ณด๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•œ๋‹ค. ์ด ํ’€์ด์—์„œ๋Š” pq๋ฅผ ์ด์šฉํ•œ๋‹ค.

pq.poll()๋กœ ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ„์„ ์„ ๋ฝ‘์•„ ๋‘ ์ •์ ์ด ๊ฐ™์€ ์ง‘ํ•ฉ์— ํฌํ•จ๋๋Š”์ง€(์‹ ์žฅ ํŠธ๋ฆฌ์— ํฌํ•จ๋๋Š”์ง€, ์—ฐ๊ฒฐ ๋๋Š”์ง€) ํ™•์ธํ•œ ๋’ค ์„œ๋กœ ๋‹ค๋ฅธ ์ง‘ํ•ฉ์— ์žˆ๋‹ค๋ฉด union()ํ•˜์—ฌ ์—ฐ๊ฒฐํ•œ๋‹ค. ์ด๋•Œ ๊ฐ€์ค‘์น˜๋ฅผ ์ตœ์ข… ๊ฐ€์ค‘์น˜ ์ถœ๋ ฅ๊ฐ’์— ํ•ฉ์‚ฐํ•œ๋‹ค.

์ฝ”๋“œ

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

/**
 * [0223] PGS ํƒ์š•๋ฒ•(Greedy) ์„ฌ ์—ฐ๊ฒฐํ•˜๊ธฐ
 * ๊ทธ๋ฆฌ๋””, ํฌ๋ฃจ์Šค์นผ, MST, Union-Find
 */

public class PGS_ํƒ์š•๋ฒ•_์„ฌ์—ฐ๊ฒฐํ•˜๊ธฐ {
    public final int FROM = 0;
    public final int TO = 1;
    public final int COST = 2;
    
    public int nodeCnt, edgeCnt;
    public int[] roots;
    // ๊ฐ€์ค‘์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฐ„์„  ์ •๋ณด๋ฅผ ์ €์žฅ
    public PriorityQueue<int[]> pq = new PriorityQueue<>((arr1, arr2) -> arr1[COST] - arr2[COST]);
    
    // Union-Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ง‘ํ•ฉ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ
    public void makeSet() {
        roots = new int[nodeCnt];
        // ๋ฃจํŠธ์— ์ž๊ธฐ ์ž์‹ ์„ ์ €์žฅํ•ด๋‘ 
        for (int i=0; i<nodeCnt; i++) roots[i] = i;
    }
    
    // Union-Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ฐ ์ง‘ํ•ฉ ๋ฃจํŠธ๋ฅผ ์ฐพ๋Š” ๋ฉ”์„œ๋“œ
    public int findRoot(int node) {
        if (roots[node] == node) return node;
        return roots[node] = findRoot(roots[node]);
    }
    
    // Union-Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋‘ ์›์†Œ๋ฅผ ๊ฐ™์€ ์ง‘ํ•ฉ์œผ๋กœ ๋งŒ๋“œ๋Š” ๋ฉ”์„œ๋“œ
    public boolean union(int node1, int node2) {
        int rootNode1 = findRoot(node1);
        int rootNode2 = findRoot(node2);
        // ๋ถ€๋ชจ๊ฐ€ ๊ฐ™์œผ๋ฉด ์ด๋ฏธ ๊ฐ™์€ ์ง‘ํ•ฉ
        if (rootNode1 == rootNode2) return false;
        // ๋ถ€๋ชจ๊ฐ€ ๋‹ค๋ฅด๋ฉด node2์˜ ๋ฃจํŠธ๋ฅผ node1์˜ ๋ฃจํŠธ๋กœ ์„ค์ •
        roots[rootNode2] = rootNode1;
        return true;
    }
    
    public int solution(int n, int[][] costs) {
        nodeCnt = n;
        edgeCnt = costs.length;
        // pq๋ฅผ ์ด์šฉํ•ด ๊ฐ€์ค‘์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฐ„์„  ์ •๋ ฌ
        sortDistances(costs);
        // ๊ฐ€์ค‘์น˜ ํ•ฉ์ด ์ตœ์†Œ๊ฐ€ ๋˜๋Š” ์ด ๊ฐ€์ค‘์น˜ ํ•ฉ ๊ตฌํ•˜๊ธฐ
        int answer = getTotalCost();
        return answer;
    }
    
    // pq์— ๊ฐ„์„ ์˜ ์ •๋ณด๋ฅผ ์ €์žฅ
    public void sortDistances(int[][] costs) {
        for (int i=0; i<edgeCnt; i++) pq.offer(costs[i]);
    }
    
    // ์ด ๊ฐ€์ค‘์น˜ ํ•ฉ ์ตœ์†Œ๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ ์ฐพ๊ธฐ
    public int getTotalCost() {
        int connected = 1;
        int totalCost = 0;
        // ์ง‘ํ•ฉ ์ƒ์„ฑํ•œ ๋’ค
        makeSet();
        // ๋ชจ๋“  ์ •์  ์—ฐ๊ฒฐ๋  ๋•Œ๊นŒ์ง€ union
        while(connected < nodeCnt) {
            int[] costInfo = pq.poll();
            // ์ถœ๋ฐœ ์ •์ ๊ณผ ๋„์ฐฉ ์ •์ ์ด ์•„์ง ์—ฐ๊ฒฐ ์•ˆ๋์œผ๋ฉด ์—ฐ๊ฒฐํ•˜๊ณ  ๊ฐ€์ค‘์น˜ ํ•ฉ์‚ฐ
            if (union(costInfo[FROM], costInfo[TO])) {
                totalCost += costInfo[COST];
                connected++;
            }
        }
        
        return totalCost;
    }
}

๐Ÿ’ก

  • ์˜ค๋žœ๋งŒ์— Union-Find ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„ํ•จ! ์—ญ์‹œ Union-Find๋Š” ๊ฐœ๋… ์ดํ•ด๋„ ์‰ฝ๊ณ  ์žฌ๋ฐŒ๋‹ค ใ…Žใ…Ž
  • ํฌ๋ฃจ์Šค์นผ ์ง๊ถ ํ”„๋ฆผ๋„ ๋‹ค์‹œ ๋ด๋ณด์ž!