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
parent = {}
rank = {}
def make_set(V):
for v in range(1, V+1):
parent[v] = v # 부모 정점을 자신으로 초기화한다.
rank[v] = 0 # rank가 높은 정점이 부모가 된다.
def find(v): # root 정점을 반환한다.
if parent[v] != v:
parent[v] = find(parent[v])
return parent[v]
'''
<Union-by-Rank>
높이를 rank로 기억한다.
1. 두 트리의 높이가 다를 때 => 높이가 작은 트리를 높이가 큰 트리에 붙인다.
2. 두 트리의 높이가 같을 때 => 한 쪽 트리의 높이를 1 증가시켜 다른 트리의 root 정점으로 한다.
'''
def union(u, v):
root1 = find(u)
root2 = find(v)
if root1 != root2: # root가 다르면 rank가 높은 정점이 부모가 된다.
if rank[root1] > rank[root2]:
parent[root2] = root1
else:
parent[root1] = root2
if rank[root1] == rank[root2]:
rank[root2] += 1 # rank가 같다면 root2를 root1의 부모로 만들었으므로 root2의 rank를 1 올린다.
'''
<Kruskal 알고리즘>
탐욕적인 방법(greedy method)을 이용하여 그래프 내의 모든 정점들을 최소 비용으로 연결
'''
def kruskal(edge_list, V):
total_cost = 0
edge_list.sort() # 정점의 리스트를 cost 기준으로 오름차순으로 정렬한다. (탐욕적인 방법을 사용하기 때문.)
make_set(V)
for e in edge_list: # 정렬된 edge_list의 원소를 차례로 가져온다.
cost, a, b = e
if find(a) != find(b): # root 정점이 다르면
union(a, b) # root 정점을 같게 만들어준다.
total_cost += cost
return total_cost
def main():
V, E = map(int, input().strip().split(' '))
edge_list = []
for _ in range(E):
a, b, c = map(int, input().strip().split(' '))
edge_list.append((c, a, b))
print(kruskal(edge_list, V))
if __name__ == '__main__':
main()
'CS 공부 > 백준 - Python' 카테고리의 다른 글
[백준 2252번] 줄 세우기 : 위상 정렬(Topology Sort) - 파이썬(Python) (1) | 2022.12.09 |
---|---|
[백준 11404번] 플로이드 : 플로이드-워셜(Floyd-Warshall) - 파이썬(Python) (0) | 2022.12.09 |
[백준 11657번] 타임머신 : 벨만-포드 알고리즘(Bellman-Ford) - 파이썬(Python) (0) | 2022.12.09 |
[백준 1753번] 최단경로 : 다익스트라(Dijkstra) 알고리즘 - 파이썬(Python) (1) | 2022.12.09 |
[백준 1991번] 트리 순회 - 파이썬(Python) (1) | 2022.12.09 |