💯Problem Solving
[BOJ] 1197 최소 스패닝 트리
date
Aug 5, 2023
slug
boj-1197
author
status
Public
tags
Python
BOJ
summary
백준 1197번 문제풀이입니다.
type
Post
thumbnail
category
💯Problem Solving
updatedAt
Aug 5, 2023 05:26 AM
문제 링크
문제
그래프가 주어졌을 때, 그 그래프의 최소 스패닝 트리를 구하는 프로그램을 작성하시오.
최소 스패닝 트리는, 주어진 그래프의 모든 정점들을 연결하는 부분 그래프 중에서 그 가중치의 합이 최소인 트리를 말한다.
문제풀이
최소 스패닝 트리는 다음과같은 방법으로 풀 수 있다.
- 크루스칼 알고리즘
- 프림 알고리즘
이 문제는 크루스칼 알고리즘으로 풀도록하겠다.
크루스칼 알고리즘이란?
정점과 간선을 입력받고, 간선의 가중치 별로 오름차순으로 정렬한뒤
간선이 낮은 순으로 그리디하게 최소 스패닝 트리에 추가하면된다.
이때 따로 트리를 만들 필요는 없고, 이 문제에서는 최소 스패닝트리의 가중치 합을 구하기 떄문에
사이클이 생기는지 안생기는지 유니온-파인드를 적용시킬 p배열을 적용시키고
사이클이 생기지 않는다면 총 가중치 변수에 가중치를 추가하고, 카운트를 1증가시켜
카운트가 노드의갯수 -1 ( 간선의 갯수는 항상 노드의 갯수 -1)이 되는 경우
남은 경우의수를 모두 스킵 ( mst 완성)
하고 총 가중치 변수를 출력하면 된다.
파이썬 문제풀이 코드
import sys sys.setrecursionlimit(10**6) input = sys.stdin.readline V, E = map(int, input().split()) p = [i for i in range(V+1)] li = [] for _ in range(E): A,B,C = map(int, input().split()) li.append((A, B, C)) li.sort(key=lambda x:x[2]) # value기준 오름차순 정렬 def find(node): if node == p[node]: # 최상위 노드인경우 return node p[node] = find(p[node]) # path compression return p[node] # 압축한 경로 def union(a, b): pa = find(a) pb = find(b) p[pb] = pa # 낮은순으로 정렬 # pb = b의 최상위 부모 노드의 값 # pa = a의 최상위 부모 노드의 값 # p[pb] = pa # pb의 부모가 가지는 값을 pa로 바꿈 # 즉, pa와 pb가 공통의 pa를 가짐으로써 둘이 연결 weighted_value = 0 count = 0 for item in li: if count == len(p)-1: # mst 완성 continue A, B, C = item if A > B: # 작은게 무조건 앞으로 temp = A A = B B = temp if find(A) != find(B): # not cycle union(A, B) weighted_value += C count += 1 print(weighted_value)
시간복잡도
- O(Mlog*N)
입력
첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이 가중치 C인 간선으로 연결되어 있다는 의미이다. C는 음수일 수도 있으며, 절댓값이 1,000,000을 넘지 않는다.
그래프의 정점은 1번부터 V번까지 번호가 매겨져 있고, 임의의 두 정점 사이에 경로가 있다. 최소 스패닝 트리의 가중치가 -2,147,483,648보다 크거나 같고, 2,147,483,647보다 작거나 같은 데이터만 입력으로 주어진다.
출력
첫째 줄에 최소 스패닝 트리의 가중치를 출력한다.