CodeingTestPrac/Java Coding Test

모든 섬사이의 다리를 만들고 비용 최소를 구하자 , kruskal union find

sung.hyun.1204 2023. 8. 6. 14:58

https://school.programmers.co.kr/learn/courses/30/lessons/42861

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

특이 조건 

 

- 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.


- 연결할 수 없는 섬은 주어지지 않습니다

 

조건을 기반으로 모든 섬은 연결이 가능하다라는 것을 이야기 하는 듯 하다.

 

 

문제를 해석했을때 아는 것을 사용할려고 다익스트라 알고리즘을 떠올렸지만,

 

사이클을 형성 하게 되면 최소 비용으로 모든 노드를 연결하지 못한다라는것을 알게 되었다.

 

-> MST 의 크루스칼 알고리즘은 가장 작은 간선을 선택을 하며 이때 순환이 안되는지를 확인을 계속 해준다.

: 간선을 기준으로 트리를 만드는 알고리즘이다.

 

그럼 순환이 안되는지는 어떻게 판단을 하나?

-> Union - find 알고리즘 

 

두 노드를 연결시 같은 그래프에 속하는 노드라면 , 사이클이 발생이 된다.

 

우리는 집합의 대표자(부모)를 지정하여 , 모든 노드가 대표자를 향하게 하는 깊이 1  그래프를 유지하여 , 검색의 속도를 높인다.

 

 

문제 후기 :  특정 알고리즘을 알면 상당하게 쉽게 풀리게 되는 문제이며 , 알고리즘의 위대함을 느낀 문제이다.

 

 

 

import java.util.*;

class Solution {
    int[] parent;

    // Union-Find 알고리즘
    public int findParent(int node) {
        if (parent[node] == node) return node;
        return parent[node] = findParent(parent[node]);
    }

    public boolean union(int a, int b) {
        a = findParent(a);
        b = findParent(b);
        if (a != b) {
            parent[b] = a;
            return true;
        }
        return false;
    }

    public int solution(int n, int[][] costs) { 
        parent = new int[n];
        for(int i = 0 ; i < n ; i++) {
            parent[i] = i ;
        }
        Arrays.sort(costs, Comparator.comparingInt( o -> o[2])) ; // sort by cost  
        
        int answer = 0 ;
        for(int[] item : costs) {
            // 최소 비용을 기준 즉 간선을 기준으로 선택을 하는  크루스칼 알고리즘
         if( union(item[0],item[1]) ) { //서롤 집합이 아니면, 연결을 한다. 
             answer += item[2] ;   // 집합이 아닌걸 더함 
            }
        }
        return answer ; 
    }
    
}