문제
풀이
처음에는 플로이드 와샬로 풀 생각을 하였다. 거쳐가야 할 정점이 두 개나 있기 때문이다.
하지만 그렇게 된다면 쓸모 없는 정점 까지의 최단 거리도 계산해야 한다.
따라서 플로이드 와샬은 O(n3)이 된다.
다른 언어는 플로이드 와샬도 되는 것 같은데 파이썬은 안된다. 따라서 다익스트라 알고리즘을 3번 사용하여
시작점 -> 경유지 1 한번, 경유지1-> 경유지2 한번, 경유지-> 도착 점 한번
이렇게 3번을 사용하거나, 경유지 1,2의 순서를 바꿔서 3번 사용하여 각각의 최단 거리를 비교하여 구한다.
처음에 시도했던 플로이드 와샬 알고리즘이다.
(시간 초과가 나는 코드)
INF = int(1e9)
n, e = map(int, input().split())
table = [[INF for _ in range(n)]for _ in range(n)]
print(table)
for i in range(e):
a, b, cost = map(int, input().split())
table[a-1][b-1] = cost
table[b-1][a-1] = cost
haveToA, haveToB = map(int, input().split())
for i in range(n):
table[i][i] = 0
for i in range(n):
for j in range(n):
for k in range(n):
table[j][k] = min(table[j][k], table[j][i]+table[i][k])
print(min(table[0][haveToA-1]+table[haveToA-1][haveToB-1]+table[haveToB-1]
[n-1], table[0][haveToB-1]+table[haveToB-1][haveToA-1]+table[haveToA-1][n-1]))
이것이 정답으로 인정된 코드이다.
import sys
import heapq
input=sys.stdin.readline
INF = int(1e9)
n, e = map(int, input().split())
table = [[]for _ in range(n)]
for i in range(e):
a, b, cost = map(int, input().split())
table[a-1].append((b-1, cost))
table[b-1].append((a-1, cost))
haveToA, haveToB = map(int, input().split())
def dijkstra(start):
q = []
distance = [INF]*n
heapq.heappush(q, (0, start))
distance[start] = 0
while q:
dist, now = heapq.heappop(q)
if distance[now] < dist:
continue
for i in table[now]:
cost = dist + i[1]
if cost < distance[i[0]]:
distance[i[0]] = cost
heapq.heappush(q, (cost, i[0]))
return distance
result = min(dijkstra(0)[haveToA-1]+dijkstra(haveToA-1)[haveToB-1]+dijkstra(haveToB-1)
[n-1], dijkstra(0)[haveToB-1]+dijkstra(haveToB-1)[haveToA-1]+dijkstra(haveToA-1)[n-1])
print(result if result < INF else -1)
또한 sys.stdin.readline을 사용하지 않아도 시간 초과가 난다...(pypy3 는 통과한다.)
백준에서 알고리즘을 할 때에는 반드시 저것을 사용해야겠다.
댓글
댓글 쓰기