[백준]1197번 - 최소 신장 트리, Kruskal, Prim

2021. 10. 21. 19:45·SW개발/코딩테스트

https://www.acmicpc.net/problem/1197

 

1197번: 최소 스패닝 트리

첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이

www.acmicpc.net

 

크루스칼 알고리즘

import sys

# 특정한 노드의 부모가 누구인지 찾는 함수
def find(target):
    if target == parent[target]:
        return target

    parent[target] = find(parent[target])
    return parent[target]

# 부모 노드를 합치는 함수
def union(a, b):
    a = find(a)
    b = find(b)

    # 더 작은 값쪽으로 부모노드를 합침
    if a < b:
        parent[b] = a
    else:
        parent[a] = b

v, e = list(map(int, (input().split())))
costs = []
visited = [1]
answer = 0
for _ in range(e):
    costs.append(list(map(int, sys.stdin.readline().split())))
    
# 크루스칼 알고리즘을 위해 가중치를 오름차순으로 정렬
costs.sort(key=lambda x: x[2])

# parent -> 부모노드가 누구인지 적혀있는 리스트
parent = [0]
for p in range(1, v+1):
    parent.append(p)

for cost in costs:
    s, e, c = cost
    # 두 노드가 사이클을 형성하지 않을 경우에만 합침
    if find(s) != find(e):
        answer += c
        union(s, e)
print(answer)

이번에도 역시 크루스칼 알고리즘과 유니온 파인드 알고리즘을 활용하였다. 저번에 풀이한 프로그래머스 문제과 같은 유형이기에 해당 알고리즘을 확실하게 이해하기 위해 풀어보았다.

문제 해결 Point

저번 문제와 같은 유형이니 간단한 설명으로 넘어가겠다.

  1. 특정한 노드의 부모노드를 찾는 함수인 find, 부모 노드를 합치는 함수인 union을 정의한다.
  2. 각 정점의 부모노드가 누구인지 적혀있는 parent 리스트에 자신의 정점번호로 초기화를 한다.
  3. costs 리스트를 순회하면서 사이클을 형성하지 않는 경우에만 가중치를 더하고, union을 해줌으로써 정답을 도출할 수 있다.

 

프림 알고리즘

import sys
import heapq

v, e = list(map(int, (input().split())))
costs = [[] for _ in range(v+1)]

# 각 정점의 가중치와 인접정보를 넣어주는 반복문
for _ in range(e):
    s, e, c = map(int, sys.stdin.readline().split())
    costs[s].append([c, e])
    costs[e].append([c, s])

# 방문 체크를 위한 리스트
visited = [False] * (v+1)
answer = 0
cnt = 0

# 최소 힙을 통해서 우선순위큐를 구현함, 가중치 순으로 정렬되게 하여 가장 낮은 cost를 고르도록 한다.
heap = []
heapq.heappush(heap, (0, 1)) # (cost, start) 시작지점은 1 노드, cost도 0
while cnt < v: # 간선의 갯수가 v-1이 되면 종료
    c, s = heapq.heappop(heap)
    if visited[s]: # 이미 방문한 노드라면 건너뜀
        continue
    visited[s] = True
    answer += c
    cnt += 1
    for cost in costs[s]:
        # 방금 방문한 정점의 간선정보를 넣어줌
        heapq.heappush(heap, cost)
print(answer)

문제 해결 Point

  1. 각 정점의 가중치와 인접정보를 넣어주어 해당 정점에 어떤 정점이 연결되어 있는 지를 보여준다.
  2. 방문 체크를 위한 리스트를 활용한다.
  3. 최소 힙을 사용해서 우선순위 큐를 구현하고, 이를 통해 가중치가 가장 낮은 간선부터 이용되게 한다.
  4. 연결된 간선의 수가 v-1이 될 때 까지 반복을 진행한다.
    1. 우선순위 큐에서 가장 가중치가 낮은 정보를 꺼낸다.
    2. 방문을 하지 않은 노드일 경우 방문처리를 수행하고, 가중치를 더한다.
    3. 방금 방문한 정점에 대한 간선 정보를 우선순위큐에 넣어준다.

 

자세한 설명은 아래의 두 링크에서 확인하실 수 있습니다. (같은 유형 다른 문제)

https://leffept.tistory.com/386

 

[프로그래머스]섬 연결하기 - 그리디, 최소 신장 트리, Prim

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 # 프림 알고리즘, 우선순위큐 이용(heapq) import..

leffept.tistory.com

https://leffept.tistory.com/383

 

[프로그래머스]섬 연결하기 - 그리디, 최소 신장 트리, Kruskal

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 # 크루스칼 알고리즘 def solution(n, costs): ans..

leffept.tistory.com

 

728x90

'SW개발 > 코딩테스트' 카테고리의 다른 글

[프로그래머스]여행경로 - DFS/BFS  (0) 2021.12.13
[프로그래머스]단어 변환 - DFS/BFS  (0) 2021.12.12
[프로그래머스]섬 연결하기 - 그리디, 최소 신장 트리, Kruskal  (0) 2021.10.21
[프로그래머스]섬 연결하기 - 그리디, 최소 신장 트리, Prim  (0) 2021.10.21
[프로그래머스]조이스틱 - 그리디  (0) 2021.10.16
'SW개발/코딩테스트' 카테고리의 다른 글
  • [프로그래머스]여행경로 - DFS/BFS
  • [프로그래머스]단어 변환 - DFS/BFS
  • [프로그래머스]섬 연결하기 - 그리디, 최소 신장 트리, Kruskal
  • [프로그래머스]섬 연결하기 - 그리디, 최소 신장 트리, Prim
Leffe_pt
Leffe_pt
개발자로서 성장하면서 배워온 지식과 경험을 공유하는 공간입니다.
  • Leffe_pt
    Leffe's tistory
    Leffe_pt
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • SW개발 (303)
        • 코딩테스트 (172)
        • 개발이야기 (23)
        • IT 용어 (17)
        • Python (22)
        • Django (46)
        • Flask (2)
        • Database (1)
        • SQLAlchemy (0)
        • Javascript (5)
        • Linux, Unix (3)
        • JAVA (2)
        • Spring (10)
      • 회고 (4)
      • 사진 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    플레이스토어
    Contributor
    배달비 공유
    배달
    django
    라이프 스타일
    음식
    오픈소스
    트리 #AVL #알고리즘 #자료구조
    배공파용
    g
    컨트리뷰터
    어플리케이션
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Leffe_pt
[백준]1197번 - 최소 신장 트리, Kruskal, Prim
상단으로

티스토리툴바