Home 백준 1504번 특정한 최단 경로
Post
Cancel

백준 1504번 특정한 최단 경로

정보

문제 바로가기 [클릭]

난이도: Gold4

관련 개념: #그래프이론 #다익스트라


조건

시간 제한메모리 제한
1초256 MB

문제

방향성이 없는 그래프가 주어진다. 세준이는 1번 정점에서 N번 정점으로 최단 거리로 이동하려고 한다. 또한 세준이는 두 가지 조건을 만족하면서 이동하는 특정한 최단 경로를 구하고 싶은데, 그것은 바로 임의로 주어진 두 정점은 반드시 통과해야 한다는 것이다.

세준이는 한번 이동했던 정점은 물론, 한번 이동했던 간선도 다시 이동할 수 있다. 하지만 반드시 최단 경로로 이동해야 한다는 사실에 주의하라. 1번 정점에서 N번 정점으로 이동할 때, 주어진 두 정점을 반드시 거치면서 최단 경로로 이동하는 프로그램을 작성하시오.


입력

첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존재하며, 그 거리가 c라는 뜻이다. (1 ≤ c ≤ 1,000) 다음 줄에는 반드시 거쳐야 하는 두 개의 서로 다른 정점 번호 v1과 v2가 주어진다. (v1 ≠ v2, v1 ≠ N, v2 ≠ 1) 임의의 두 정점 u와 v사이에는 간선이 최대 1개 존재한다.


출력

첫째 줄에 두 개의 정점을 지나는 최단 경로의 길이를 출력한다. 그러한 경로가 없을 때에는 -1을 출력한다.


예제 입출력 1

입력

1
2
3
4
5
6
7
8
4 6
1 2 3
2 3 3
3 4 1
1 3 5
2 4 5
1 4 4
2 3

출력

1
7

코드(파이썬)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import heapq
import sys


def diji(start):
    d = [MAX_DIST] * (n+1)
    v = [1] + [0] * (n)
    queue = [(0, start)]
    d[start] = 0
    
    while queue and 0 in v:
        dist, node = heapq.heappop(queue)
        v[node] = 1
        
        for next_dist, next_node in edges[node]:
            if next_dist+dist < d[next_node] and v[next_node] == 0:
                d[next_node] = next_dist+dist
                heapq.heappush(queue, (next_dist+dist, next_node))
                
    return d
                
n, e = map(int, sys.stdin.readline().split())
edges = {i:list() for i in range(1, n+1)}
MAX_DIST = 1000 * 200001

for _ in range(e):
    n1, n2, d = map(int ,sys.stdin.readline().split())
    edges[n1].append((d, n2))
    edges[n2].append((d, n1))
wp1, wp2 = map(int, sys.stdin.readline().split())
    
between_wp = diji(wp1)[wp2]
path = [0, 0]

for start in [1, n]:
    d = diji(start)
    
    path[0] += d[wp1] if start == 1 else d[wp2]
    path[1] += d[wp2] if start == 1 else d[wp1]

if between_wp == MAX_DIST or max(path) >= MAX_DIST:
    print(-1)
else:
    print(between_wp + min(path))


특이사항

  • 해결방식
    • [a - 경유지1 - 경유지2 - b] 와 [b - 경유지1 - 경유지2 - a]의 경로를 비교
    • 각 점들 간의 경로는 다익스트라를 이용해 계산

참고문헌

-

This post is licensed under CC BY 4.0 by the author.

백준 1027번 고층 건물

백준 1806번 부분합

Comments powered by Disqus.