해당 문제는 다익스트라(Dijkstra) 알고리즘을 응용하여 풀었으므로 해당 알고리즘에 대한 설명은 아래 링크에서 확인하면 된다.
2021.03.18 - [# Coding/# Algorithm] - [보기 쉬운 Algorithm] 다익스트라(Dijkstra) 알고리즘 - Python
[보기 쉬운 Algorithm] 다익스트라(Dijkstra) 알고리즘 - Python
'다익스트라(Dijkstra) 알고리즘'은 비용(가중치) 간선이 있는 노드 그래프의 최단 거리를 구하는 알고리즘 시간을 줄이기 위해서 파이썬 모듈 중 최소 힙을 구현할 수 있는 heapq를 사용한다. ↳ list
joinmycode.tistory.com
그래프를 먼저 입력받아 양방향 그래프를 작성한 후 모든 거리(가중치)를 1로 계산하여 다익스트라 알고리즘을 사용하였다.
<입력 1>
n = int(input())
graph = {i: [] for i in range(1, n+1)}
총인원수 n을 입력 받고, 그 크기만큼의 graph 키를 설정하였다.
<입력 2>
p1, p2 = map(int, input().split())
for _ in range(int(input())):
x, y = map(int, input().split())
graph[x].append(y)
graph[y].append(x)
촌 수를 구하고 싶은 두 사람 p1, p2를 입력받는다.
관계의 개수를 입력받은 만큼 반복한다. 관계 선이 있는 두 사람 x, y를 입력받고 양방향으로 그래프를 그린다. 부모-자식, 자식-부모로 타고 갈 수 있기 때문이다.
<다익스트라 알고리즘>
import heapq
def dijkstra(graph, start_node):
distances = {i: float('inf') for i in graph}
distances[start_node] = 0
queue = [[distances[start_node], start_node]]
while queue:
current_distance, current_node = heapq.heappop(queue)
if current_distance > distances[current_node]:
continue
for next_node in graph[current_node]:
distance = current_distance+1
if distance < distances[next_node]:
distances[next_node] = distance
heapq.heappush(queue, [distance, next_node])
return distances
속도 개선을 위해 최소 큐를 구현할 수 있게 heapq 모듈을 import했다.
start_node로 부터 계산되는 거리를 distances에 받을 수 있게 모든 값을 최대 수인 'inf'로 설정했다.
start_node의 거리는 포함하지 않으므로 0으로 설정한다.
queue에 우선순위가 되는 distances를 설정하고, 출발 노드인 start_node를 넣는다.
queue에서 현재 거리와 현재 기준 노드를 받아온다. 만약 이 거리가 distances에 있는 거리보다 길 경우 해당 값을 무시하고 다음 queue의 값으로 넘어간다.
짧을 경우 해당 노드로부터 갈 수 있는 모든 노드를 graph에서 받아온다. 모든 움직임의 거리가 1이므로, 새 거리는 현재 거리에서 1을 더한 값이고, 이 새거리가 distances에 있는 거리보다 짧은 경우, distances의 값을 갱신해주고, 해당 거리와 노드를 queue에 넣는다.
모든 반복이 끝난 후 distances를 반환해준다.
<호출 및 출력>
answer = dijkstra(graph, p1)[p2]
print(answer if answer != float('inf') else -1)
p1을 기준으로 반환된 distacnes의 p2와의 관계를 answer에 담는다.
만약 answer의 값이 'inf'인 경우 도착할 수 없으므로 -1로 값을 바꿔 출력하고, 아닌 경우 그대로 출력한다.
<전체 코드>
import heapq
def dijkstra(graph, start_node):
distances = {i: float('inf') for i in graph}
distances[start_node] = 0
queue = [[distances[start_node], start_node]]
while queue:
current_distance, current_node = heapq.heappop(queue)
if current_distance > distances[current_node]:
continue
for next_node in graph[current_node]:
distance = current_distance+1
if distance < distances[next_node]:
distances[next_node] = distance
heapq.heappush(queue, [distance, next_node])
return distances
n = int(input())
graph = {i: [] for i in range(1, n+1)}
p1, p2 = map(int, input().split())
for _ in range(int(input())):
x, y = map(int, input().split())
graph[x].append(y)
graph[y].append(x)
answer = dijkstra(graph, p1)[p2]
print(answer if answer != float('inf') else -1)
'# Coding > # 백준' 카테고리의 다른 글
[백준 / 1068] 트리 - Python (0) | 2021.03.25 |
---|---|
[백준 / 1005] ACM Craft - Python (0) | 2021.03.24 |
[백준 / 1012] 유기농 배추 - Python (0) | 2021.03.19 |
[백준 / 2667] 단지번호붙이기 - Python (0) | 2021.03.19 |
[백준 / 2606] 바이러스 - Python (0) | 2021.03.19 |