-
100일 동안 매일 알고리즘을 하면? - 14일차알고리즘 2022. 1. 20. 02:03
100일 동안 매일 알고리즘을 하면? - 14일차
https://programmers.co.kr/learn/courses/30/lessons/42861
코딩테스트 연습 - 섬 연결하기
4 [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] 4
programmers.co.kr
이 문제는 크루스칼(Kruskal) 알고리즘으로 풀 수 있는 문제이다.
크루스칼 알고리즘을 이해하기 위해서 2가지 배경지식이 필요한데, 첫번째는 spanning tree 이고, 두번째는 union-find 이다.
1. spanning tree 란?
spanning tree 는 n 개의 정점을 (n-1) 개의 간선을 사용해서 모두 연결하는 트리이다.
여러 spanning tree 중, 모든 간선의 비용 합이 가장 작은 spanning tree 를 (MST: minimun spanning tree) 라고 부른다.
크루스칼 알고리즘은 이 MST 를 구하는 알고리즘이다.
2. union-find 란?
union-find 를 이해하기 위해선 먼저 서로소 집합을 알아야 한다.
서로소 집합이란, 말그대로 두 집합의 교집합이 공집합인 집합이다.
서로소 집합을 조금 확장한게 서로소 트리이다.
우리는 서로소 트리를 이용해서 그래프에서 싸이클이 생성되었는지 알 수 있다.
예를들어 x1 과 x2 를 연결하는 간선을 만들려고 할때, 이 간선이 싸이클을 형성하는지 알고싶다.
그럼, 특정 x1, x2 각각의 서로소트리 최상단 부모의 값을 비교함으로서, 두 부모가 같으면, 해당 간선은 싸이클을 형성하고, 그렇지 않으면 싸이클을 형성하지 않는다는 것을 알 수 있다.
union 은 두 서로소 집합을 합치는 함수이고, find 는 최상단 부모 노드를 리턴하는 함수이다.
3. 크루스칼 알고리즘 사용법
크루스칼 알고리즘은 MST 를 만드는 알고리즘이며, MST 를 만들기 위한 조건이 2가지 있다.
첫번째는 MST 가 n 개의 노드를 가진다고 가정했을때 n-1 개의 간선으로 구성되어 있어야하고,
두번째는, 싸이클을 형성하면 안된다.
먼저, 비용을 기준으로 오름차순으로 정렬한다.
그 다음, 간선을 1개씩 pick 하면서, 해당 간선이 싸이클을 형성하지 않으면, answer 에 비용을 추가한다.
만약 싸이클을 형성하면 answer에 비용을 추가하지 않고 넘어간다.
총 n - 1 개를 Pick 했으면 answer 를 리턴한다.
4. 소스코드
def solution(n, costs): costs.sort(key=lambda x: x[2]); count = n - 1; answer = 0; roots = [0] * n; for i in range(n): roots[i] = i; def find(node, roots): if (node == roots[node]): return node; else: return find(roots[node], roots); def union(parentNode, childNode, roots): x = find(parentNode, roots); y = find(childNode, roots); roots[y] = x; for cost in costs: node1 = cost[0]; node2 = cost[1]; value = cost[2]; if (find(node1, roots) == find(node2, roots)): continue; else: answer += value; union(node1, node2, roots); count -= 1; if (count == 0): break return answer;
'알고리즘' 카테고리의 다른 글
[프로그래머스] 정수 삼각형 (파이썬) (0) 2022.02.02 [프로그래머스] N으로 표현 (파이썬) (0) 2022.02.02 100일 동안 매일 알고리즘을 하면? - 13일차 (0) 2022.01.19 100일 동안 매일 알고리즘을 하면? - 12일차 (0) 2022.01.11 100일 동안 매일 알고리즘을 하면? - 11일차 (0) 2022.01.10