MST
- 그래프에서 최소 비용문제
- 모든 정점을 연결하는 간선들의 가중치의 합이 최소가 되는 트리
- 두 정점 사이의 최소 비용의 경로 찾기
- 신장 트리
- n개의 정점으로 이루어진 무방향 그래프에서 n개의 정점과 n-1 개의 간선으로 이루어진 트리
- 최소 신장 트리
- 무방향 가중치 그래프에서 신장 트리를 구성하는 간선들의 가중치의 합이 최소인 신장 트리
Prim 알고리즘
- 하나의 정점에서 연결된 간선들 중에 하나씩 선택하면서 MST를 만들어 가는 방식
- 임의 정점을 하나 선택해서 시작
- 선택한 정점과 인접하는 정점들 중의 최소 비용의 간선이 존재하는 정점을 선택
- 모든 정점이 선택될 때까지 위의 과정 반복
- 서로소인 2개의 집합 정보를 유지
- 트리 정점들 : MST를 만들기 위해 선택된 정점들
- 비트리 정점들 : 선택 되지 않은 정점들
import heapq as hq
def prim(start):
heap = list()
connected = [False] * (Node_cnt + 1)
sum_w = 0
hq.heappush(heap, (0, start))
sum_w = 0
print('################')
print('MST')
while heap:
weight,v = hq.heappop(heap)
if not connected[v]:
connected[v] = True
sum_w += weight
print('Connected Nodes:', v, 'Weight:',weight)
for i in range(1, Node_cnt + 1):
if graph[v][i] != 0 and not connected[i]:
hq.heappush(heap, (graph[v][i], i))
print('Sum of weight:', sum_w)
KRUSKAL 알고리즘
- 간선을 하나씩 선택해서 MST를 찾는 알고리즘
- 최초, 모든 간선을 가중치에 따라 오름차순으로 정렬
- 가중치가 가장 낮은 간선부터 선택하면서 트리를 증가시킴
- 사이클이 존재하면 다음으로 가중치가 낮은 간선 선택
- n-1개의 간선이 선택될 때 까지 반복
import sys
def find_parent(parent, a):
if parent[a] != a:
parent[a] = find_parent(parent, parent[a])
return parent[a]
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
input = sys.stdin.readline
v, e = map(int, input().split())
parent = [0] * (v + 1)
for i in range(1, v + 1):
parent[i] = i
edges = []
result = 0
for _ in range(e):
a, b, cost = map(int, input().split())
edges.append((a, b, cost))
edges.sort(key=lambda x: x[2])
for a, b, cost in edges:
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
result += cost
print(result)
최단 경로
- 최단 경로의 정의
- 간선의 가중치가 있는 그래프에서 두 정점 사이의 경로들 중에 간선의 가중치의 합이 최소인 경로
- 하나의 시작 정점에서 끝 정점까지의 최단 경로
- 모든 정점들에 대한 최단 경로
다익스트라 알고리즘
- 시작 정점에서 거리가 최소인 정점을 선택해 나가면서 최단 경로를 구하는 방식이다
- 시작정점(s)에서 끝정점(t)까지의 최단 경로에 정점 x가 존재한다
- 이때, 최단 경로는 s에서 x까지의 최단 경로와 x에서 t까지의 최단 경로 구성된다
- 탐욕 기법을 사용한 알고리즘으로 MST의 프림 알고리즘과 유사하다
graph = {
'A': {'B': 8, 'C': 1, 'D': 2},
'B': {},
'C': {'B': 5, 'D': 2},
'D': {'E': 3, 'F': 5},
'E': {'F': 1},
'F': {'A': 5}
}
import heapq
def dijkstra(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0
queue = []
heapq.heappush(queue, [distances[start], start])
while queue:
current_distance, current_destination = heapq.heappop(queue)
if distances[current_destination] < current_distance:
continue
for new_destination, new_distance in graph[current_destination].items():
distance = current_distance + new_distance
if distance < distances[new_destination]:
distances[new_destination] = distance
heapq.heappush(queue, [distance, new_destination])
return distances