Posts [programmers] 섬 연결하기 (python)
Post
Cancel

[programmers] 섬 연결하기 (python)

섬 연결하기 문제 바로가기

코딩 테스트 연습 > 탐욕법(Greedy) > 섬 연결하기

level 3

해결 방법

주요 변수 설명

p 리스트를 통해 섬(노드)이 어느 섬과 연결되었는지 또는 연결이 안되었는지 확인가능하다.

  • p의 초기 설정(n = 4일 때 가정)

    p = [0, 1, 2, 3]

    각 인덱스마다 자기 자신의 섬과 연결된 것으로 기본 설정을 한다.

  • ex) 초기 설정에서 만약 0번 섬과 1번 섬이 연결되었을 경우 p는 다음과 같다.

    p = [0, 0, 2, 3]

    1번 섬의 부모노드를 0번 섬으로 저장하여 연결됨을 보인다.

구현 과정

Kruskal MST 알고리즘 이용 ★

  1. costs에서 가중치가 작은 순으로 정렬한다.

  2. while 문을 통해서 가중치가 작은 순서대로 costs를 pop하여 확인한다.

    u, v, wt = costs.pop(0)

    1. 연결된 u, v의 섬이 서로 사이클이 없다면 (즉 연결가능하다면!)

      if find(u) != find(v):

      1. 두 섬을 연결한다. union(u, v)
      2. 출력할 최소비용을 저장한 cost 변수에 가중치를 더한다.
      3. 간선을 연결했기에 tree_edges 에 1을 더한다.
    2. 연결된 u, v의 섬이 사이클이 있다면 패스!

      • 이유

        최소 비용으로 모든 섬을 연결하는 mst의 조건을 만족하기 위해서는 사이클이 없는 섬끼리 연결해야한다!

    → mst의 조건인 간선의 개수가 n - 1인 경우 break를 통해 종료시킨다.

구현한 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def solution(n, costs):
    costs.sort(key = lambda x: x[2]) # 가중치가 작은 순으로 정렬하기
    p = [i for i in range(n)] 
    tree_edges = 0
    cost = 0

    def find(u): # 연결된 상위 부모노드를 찾아주는 함수
        if u != p[u]:
            p[u] = find(p[u])
        return p[u]

    def union(u, v): # u, v의 섬을 연결해주어 간선이 연결되는 함수
				# 각 섬의 부모 노드를 찾기
        root1 = find(u) 
        root2 = find(v)
        p[root2] = root1 # 부모노드를 갱신하여 간선 연결하기

    while True:
        if tree_edges == n - 1: # mst 조건 : 모든 섬이 통하는 경우
            break
        u, v, wt = costs.pop(0)
        if find(u) != find(v): # 사이클이 아니라면! 연결 가능한 조건
            union(u, v) # 간선 연결하기
            cost += wt # 비용에 가중치 추가하기
            tree_edges += 1 # 간선 추가됨을 확인할 수 있도록 변수에 저장하기
    return cost
This post is licensed under CC BY 4.0 by the author.

[Algorithm] MST에 대한 모든 것! with 크루스칼 알고리즘, 프림 알고리즘 (python)

-

Comments powered by Disqus.