안녕하세요, 여러분! 오늘은 다익스트라 알고리즘에 대해 깊이 있게 알아보고, 실제 코딩 테스트에서 자주 출제되는 문제를 풀어보도록 하겠습니다. 다익스트라 알고리즘은 가중치가 있는 미그래프에서 최단 경로를 찾는 알고리즘으로, 주로 네트워크 최단 경로 문제를 해결하는 데 사용됩니다.
1. 다익스트라 알고리즘 개요
다익스트라 알고리즘은 1956년 에드가 다익스트라에 의해 개발된 최단 경로 알고리즘으로, 특정 정점에서 시작하여 다른 모든 정점으로 가는 최단 경로를 찾는 데 사용됩니다. 이 알고리즘은 음수 가중치를 허용하지 않으며, 그래프가 연결되어 있다고 가정합니다.
1.1 알고리즘 동작 원리
- 시작 정점을 선택하고, 그 정점의 거리를 0으로 설정합니다.
- 나머지 모든 정점의 거리를 무한대로 초기화합니다.
- 최소 거리가 결정되지 않은 정점 중에서 가장 거리가 짧은 정점을 선택합니다.
- 선택된 정점을 기준으로 인접 정점들의 거리를 업데이트합니다.
- 모든 정점의 거리가 결정될 때까지 반복합니다.
2. 문제 설명
이제 실제 문제를 통해 다익스트라 알고리즘을 적용해봅시다.
문제: 최단 경로 찾기
입력으로 주어진 그래프가 주어졌을 때, 특정 시작 정점에서 모든 다른 정점까지의 최단 경로를 구하는 프로그램을 작성하시오.
입력 조건
- 첫째 줄에 정점의 개수
V
와 간선의 개수E
가 주어진다. (1 ≤ V ≤ 20, 1 ≤ E ≤ 100) - 둘째 줄부터 E개의 줄에 걸쳐 각각의 간선에 대한 정보가 주어진다. 간선의 정보는 시작 정점
A
, 도착 정점B
, 가중치C
형태로 주어진다. - 마지막 줄에는 시작 정점
K
가 주어진다.
출력 조건
시작 정점 K
에서 다른 모든 정점까지의 최단 거리를 출력합니다. 만약 어떤 정점까지의 경로가 없다면 INF
를 출력합니다.
3. 문제 풀이 과정
3.1 그래프 표현
우선 주어진 간선 정보를 바탕으로 그래프를 인접 리스트로 표현합니다. 파이썬에서는 딕셔너리(Dictionary)를 사용하여 각 정점과 그 정점과 연결된 다른 정점 및 가중치를 저장할 수 있습니다.
from collections import defaultdict
import heapq
def create_graph(edges):
graph = defaultdict(list)
for A, B, C in edges:
graph[A].append((B, C))
return graph
3.2 다익스트라 알고리즘 구현
이제 실제 다익스트라 알고리즘을 구현합니다. 이 알고리즘은 우선순위 큐를 활용하여 현재까지의 최단 경로를 효율적으로 업데이트합니다.
def dijkstra(graph, start, V):
distances = {vertex: float('inf') for vertex in range(1, V + 1)}
distances[start] = 0
priority_queue = [(0, start)]
while priority_queue:
current_distance, current_vertex = heapq.heappop(priority_queue)
if current_distance > distances[current_vertex]:
continue
for neighbor, weight in graph[current_vertex]:
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(priority_queue, (distance, neighbor))
return distances
3.3 최종 코드
모든 요소를 종합하여 최종적인 코드를 작성합니다. 입력을 받고 결과를 처리하는 부분도 포함되어 있습니다.
def main():
V, E = map(int, input().split())
edges = [tuple(map(int, input().split())) for _ in range(E)]
K = int(input())
graph = create_graph(edges)
distances = dijkstra(graph, K, V)
for vertex in range(1, V + 1):
if distances[vertex] == float('inf'):
print("INF")
else:
print(distances[vertex])
if __name__ == "__main__":
main()
4. 시간 복잡도
다익스트라 알고리즘의 시간 복잡도는 사용된 데이터 구조에 따라 달라집니다. 일반적으로 우선순위 큐를 사용할 경우 O((V + E) log V)입니다. 여기서 V
는 정점의 수, E
는 간선의 수입니다.
5. 결론
이번 강좌에서 다익스트라 알고리즘을 통해 최단 경로 문제를 해결하는 방법을 배우고, 실제 입력을 다루어 보았습니다. 이 알고리즘은 네트워크, 게임 개발 등 다양한 분야에서 활용될 수 있으므로, 잘 숙지해두면 좋습니다.
추가 문제를 통해 더 다양한 상황을 연습해 보시기 바랍니다. 다음 강좌에서는 다른 알고리즘을 살펴보도록 하겠습니다. 감사합니다!