728x90
📢 '이것이 코딩 테스트다 with 파이썬' 책을 공부하고 복습하기 위해 작성했습니다.
문제
방문 판매원 A는 현재 1번 회사에 있으며, X번 회사에 방문해 물건을 판매하고자 한다.
공중 미래 도시에서 특정 회사에 도착하기 위해서는 회사끼리 연결되어 있는 도로를 이용하는 방법이 유일하다. 또한 연결된 2개의 회사는 양방향으로 이동할 수 있다. 도로는 정확히 1만큼의 시간으로 이동할 수 있다.
또한 방문 판매원 A는 소개팅에도 참석하고자 한다. 소개팅 상대는 K번 회사에 존재한다.
따라서 방문 판매원 A는 1번 회사에서 출발하여 K번 회사를 방문한 뒤에 X번 회사로 가는 것이 목표이다. 이때, 방문 판매원 A는 가능한 한 빠르게 이동하고자 한다. 방문 판매원이 회사 사이를 이동하게 되는 최소 시간을 계산하라.
입력 조건
- 첫째 줄에 전체 회사의 개수 N과 경로의 개수 M이 공백으로 구분되어 차례대로 주어진다. (1 ≤ N, M ≤ 100)
- 둘째 줄부터
M + 1
번째 줄에는 연결된 두 회사의 번호가 공백으로 구분되어 주어진다. M + 2
번째 줄에는 X와 K가 공백으로 구분되어 차례대로 주어진다. (1 ≤ K ≤ 100)
출력 조건
- 첫째 줄에 방문 판매원 A가 K번 회사를 거쳐 X번 회사로 가는 최소 이동 시간을 출력한다.
- 만약 X번 회사에 도달할 수 없다면,
-1
을 출력한다.
입력 예시 1
5 7
1 2
1 3
1 4
2 4
3 4
3 5
4 5
4 5
출력 예시 1
3
입력 예시 2
4 2
1 3
2 4
3 4
출력 예시 2
-1
나의 풀이
import pprint
# 회사 N개, 경로 M개
N, M = map(int, input().split())
"""
# 플로이드 워셜
모든 경로에 대한 최소 비용 계산
graph[i][j] = i -> j 로 가는 최소 비용
"""
INF = int(1e9)
graph = [[INF] * (N+1) for _ in range(N+1)]
# 자기 자신 i -> i
for i in range(N+1):
graph[i][i] = 0
# 연결된 경로 비용은 1, 양방향
for _ in range(M):
i, j = map(int, input().split())
graph[i][j] = 1
graph[j][i] = 1
# a -> b 로 바로 이동하는 경우 = graph[a][b]
# a -> b 의 경로에서 k번 노드를 거쳐 가는 경우 = graph[a][k] + graph[k][b]
for k in range(1, N+1):
for a in range(1, N+1):
for b in range(1, N+1):
graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])
X, K = map(int, input().split())
# 1 -> K 최소 시간 + K -> X 최소 시간
result = graph[1][K] + graph[K][X]
print(-1) if result >= INF else print(result)
해설
전형적인 플로이드 워셜 알고리즘 문제이다. N의 범위가 100 이하로 매우 한정적이기 때문에 플로이드 워셜 알고리즘을 이용하는 것이 유리하다.
1번 노드에서 K를 거쳐 X로 가는 최단 거리 = 1번 노드에서 K까지의 최단 거리 + K에서 X까지의 최단 거리
728x90
'Algorithm' 카테고리의 다른 글
[이코테] 09. 그래프 이론 (0) | 2024.01.15 |
---|---|
[이코테] 08. 최단 경로 - 전보 (2) | 2024.01.11 |
[이코테] 08. 최단 경로 (2) | 2024.01.11 |
[이코테] 07. 다이나믹 프로그래밍 - 효율적인 화폐 구성 (0) | 2024.01.09 |