최소 신장 트리 예제 - 2

문제 분석

  • 문제 조건에서 데이터의 크기는 매우 작은 편이라 시간 복잡도의 제약은 크지 않다.

  • 몇 개의 단계로 나눠서 생각해야 한다.

    • 먼저 주어진 지도에서 섬으로 표현된 값을 각각의 섬마다 다르게 표현해야 한다.

    • 그 이후 각 섬의 모든 위치에서 다른 섬으로 연결할 수 있는 에지가 있는지 확인해 에지 리스트를 만든다.

    • 이후에는 최소 신장 트리를 적용하면 문제를 해결할 수 있다.

손으로 풀어보기

  1. 지도의 정보를 2차원 리스트에 저장하고 섬으로 표시된 모든 점에서 BFS를 실행해 섬을 구분한다.

  2. 모든 섬에서 상하좌우로 다리를 지어 다른 섬으로 연결할 수 있는지 확인한다. 연결할 곳이 현재 섬이면 탐색 중단, 바다라면 탐색을 계속 수행한다. 다른 섬을 만났을 때 다리의 길이가 2 이상이면 이 다리를 에지 리스트에 추가한다.

  3. 전 단계에서 수집한 모든 에지를 오름차순 정렬해 최소 신장 트리 알고리즘을 수행한다. 알고리즘이 끝나면 사용한 에지의 합을 출력한다.

슈도코드

n, m(행렬 크기)
dx, dy(네 방향 탐색 상수)
map(맵 정보 리스트)
visit(BFS 방문 리스트)

for n 반복:
    map 정보 저장

num(섬 번호)
sumlist(모든 섬 정보 이중 리스트)
mlist(1개의 섬 정보 리스트)

addNode(i, j, qu):
    map에서 i, j 위치에 섬 번호 저장
    해당 위치 방문 표시
    mlist에 해당 노드 추가
    BFS를 위한 큐에 해당 노드 추가

BFS(i, j):
    i, j위치에서 네 방향으로 연결된 모든 노드를 탐색하여 1개 섬의 영역을 저장
    연결된 새로운 노드가 확인하면 addNode를 통해 정보 저장

for i n 반복:
    for j m 반복:
        BFS(i, j)  # BFS를 실행해 하나의 섬 정보를 가져오기
        BFS 결과(하나의 섬 정보)를 sumlist에 추가
        섬 번호 1 증가

pq(우선순위 큐)

for sumlist:
    now(sumlist에서 추출)
    for now :
        1개의 섬의 모든 위치에서 만들 수 있는 다리 정보 저장
        # 우선순위 큐에 에지 정보 저장

find(a):
    a가 대표 노드면 리턴
    아니면 a의 대표 노드값을 find(parent[a])값으로 저장

union(a, b):
    a와 b의 대표 노드 찾기
    두 원소의 대표 노드끼리 연결
    
parent(대표 노드 저장 리스트)

useEdge(에지 사용 횟수 변수)
result(정답 변수)

while 큐가 빌 때까지:
    큐에서 에지 정보 가져오기
    if 에지 시작점과 끝점의 부모 노드가 다르면:
        union 수행
        에지 가중치 result에 더하기
        에지 사용 횟수 1 증가

if 사용한 에지의 수가 노드-1이면:
    result 출력
else:
    -1 출력

코드 구현 - 파이썬

코드 구현 - 자바

Last updated