알고리즘/학습 내용

[파이썬] 크루스칼 알고리즘

개발윗미 2021. 9. 15. 17:48

[신장 트리란 ?]

신장 트리는 그래프에서 모든 노드를 포함하면서 사이클이 존재하지 않는 부분 그래프를 의미한다.

 

[크루스칼 알고리즘이란 ?]

크루스칼 알고리즘은 대표적인 최소 신장 트리 알고리즘이다. 그리디 알고리즘으로 분류가 되며, 동작 과정은 다음과 같다.

 

1. 간선 데이터를 비용에 따라 오름차순으로 정렬한다.

 

2. 간선을 하나씩 확인하며 현재의 간선이 사이클을 발생시키는지 확인한다.

 

    만약, 사이클이 발생하지 않는다면 최소 신장 트리에 포함시키고, 사이클이 발생한다면 최소 신장 트리에 포함시키지 않는다.

 

3. 모든 간선에 대하여 2번의 과정을 반복한다.

 

 

구체적인 동작 과정은 아래의 게시물에서 확인할 수 있다.

 

https://unie2.tistory.com/37?category=873806 

 

크루스칼 알고리즘(Kruskal Algorithm)

크루스칼 알고리즘은 가장 적은 비용으로 모든 노드를 연결하기 위해 사용하는 알고리즘이다. 즉, 크루스칼 알고리즘은 최소 비용 신장 트리를 만들기 위한 대표적인 알고리즘이다. 그림과 같

unie2.tistory.com

 

[크루스칼 알고리즘 예제]

# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x) :
  # 루트 노드를 찾을 때까지 재귀 호출
  if parent[x] != x :
    parent[x] = find_parent(parent, parent[x])
  return parent[x]

# 두 원소가 속한 집합을 합치기
def union_parent(parent, a, b) :
  a = find_parent(parent, a)
  b = find_parent(parent, b)

  if a < b :
    parent[b] = a
  else :
    parent[a] = b

# 노드의 개수와 간선의 개수 입력 받기
v, e = map(int, input().split())
parent = [0] * (v + 1) #부모 테이블 초기화

# 모든 간선을 담을 리스트와 최종 비용을 담을 변수 선언
edges = []
result = 0

# 부모 테이블상에서 부모를 자기 자신으로 초기화
for i in range(1, v + 1) :
  parent[i] = i

# 모든 간선에 대한 정보를 입력 받기
for _ in range(e) :
  a, b, cost = map(int, input().split())
  # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정
  edges.append((cost, a, b))

# 간선을 비용순으로 정렬
edges.sort()

# 간선을 하나씩 확인
for edge in edges :
  cost, a, b = edge
  # 사이클이 발생하지 않는 경우에만 집합에 포함
  if find_parent(parent, a) != find_parent(parent, b) :
    union_parent(parent, a, b)
    result += cost

print(result) # 최소 신장 트리에 포함되어 있는 모든 간선 비용의 합 출력

 


출처

이것이 코딩 테스트다 with 파이썬 - 나동빈 저

'알고리즘 > 학습 내용' 카테고리의 다른 글

[파이썬] 소수 (Prime Number)  (0) 2021.09.15
[파이썬] 위상 정렬  (0) 2021.09.15
[파이썬] 순차 탐색과 이진 탐색  (0) 2021.08.27
정렬 알고리즘  (0) 2021.08.25
재귀 함수 (Recursive Function)  (0) 2021.08.23