새소식

PS/CodeUp

[CodeUp/2840] R&E 가는길(Large) (Python)

  • -

Problem : R&E가는길 (Large) (codeup.kr)

Status : Solved

Time : 00:28:16

 


 

문제 설명

 

더보기

현호가 GSHS에서 R&E 교수님을 뵈러 S대학교를 가려고 한다.

경유하는 지역(GSHS와 S대학교 포함)이 n개, 한 지역에서 다른 지역으로 가는 방법이 총 m개이며 GSHS는 지역 1이고 S대학교는 지역 n이라고 할 때 현호가 S대학교로 가는데 드는 최소 비용을 구하시오.

단, n은 10000 이하, m은 100000 이하, 그리고 한 지역에서 다른 지역으로 가는 데에 필요한 비용은 모두 1000이하 양의 정수이며 한 지역에서 다른 지역으로 가는 어떠한 방법이 존재하면 같은 방법과 비용을 통해 역방향으로 갈 수 있다.

다음 그래프는 예를 보여준다. (단, 정점a->정점b로의 간선이 여러 개 있을 수 있으며, 자기 자신으로 가는 정점을 가질 수도 있다.)

 

최소 비용이 드는 경로 : 1→3→5→7
최소 비용 : 69+59+21=149

 

입력 및 출력

 

더보기

입력

첫째 줄에는 한 칸씩의 공백을 두어 지역의 수와 한 지역에서 다른 지역으로 가는 총 방법의 수가 주어지며 두 번째 줄부터 m+1줄까지는 한 칸씩의 공백을 두어 각 지역과 그 지역에서 갈 수 있는 지역 그리고 그 지역으로 가는데 필요한 비용이 주어진다.

 

출력

첫째 줄에 S대학교를 가는데 드는 최소 비용을 출력한다. 만약 현호가 S대학교를 갈 수 없다면 "Impossible"를 첫째 줄에 출력한다.(단, 큰따옴표는 출력하지 않는다)

 

입력 예시

7 11

1 2 47

1 3 69

2 4 57

2 5 124

3 4 37

3 5 59

3 6 86

4 6 27

4 7 94

5 7 21

6 7 40

 

출력 예시

149

 

 


 

풀이

*주의 : 이 문제는 불완전한 테스트케이스를 포함하고 있습니다!

 

요즘 문제 풀이를 올리는 기준에 대해 조금 고민이 많아졌다. 너무 쉬운 문제를 양산하듯 올리자니 전체적인 퀄리티를 떨어뜨리는것 같고, 그러지 않자니 포스팅하지 않는 날도 많아져서... 코드업이 테스트케이스를 제공해주는 장점이 있지만, 이런 문제 난이도에 대한 객관적인 rating이 부족한 게 아쉽다.

 

이 문제의 풀이부터 짚고 넘어가자면, 단순히 0을 시작점, 1을 끝점으로 하는 다익스트라 알고리즘을 적용해 주면 된다. 파이썬의 메모리 제한을 고려하자면 dist값을 저장하는 경우 2차원 리스트 대신 딕셔너리를 사용하는게 더 효율적이며(n값에 비해 m값이 매우 작다. n의 제곱의 경우의 수가 나올 수 있지만 m값은 100000 이하기 때문이다), 최소 경로를 구하고 싶으므로 두 노드 사이에 여러 경로가 존재한다면 그 중 최소값만을 저장하면 된다.

 

문제는 다음 테스트케이스다 :

잘못된 테스트케이스

이 경우는 입력 자체가 올바르지 않은 경우이다. 둘째 줄부터 m+1개의 줄에는 세 정수가 와야 하기 때문. 일반적인 풀이로는 절대 정답을 맞출 수 없다. 따라서 이러한 상황에 대한 예외 처리를 해주는 편법이 필요하다. 파이썬의 경우 try except문으로 우선 해결했다.

 

풀이 코드

from heapq import heappush, heappop
import sys

input = sys.stdin.readline

try :
  n, m = map(int, input().split())
  MAX = float('inf')
  dist_dict = { key : dict() for key in range(n)}
  dist_list = [MAX]*n
  
  for _ in range(m) :
    a, b, c = map(int, input().split())
    if a-1 not in dist_dict[b-1] or dist_dict[b-1][a-1] > c :
      dist_dict[b-1][a-1] = dist_dict[a-1][b-1] = c
  
  q = [(0,0)]
  
  while q :
    cost, node = heappop(q)
    if node == m-1 or dist_list[node] <= cost :
      continue
    dist_list[node] = cost
    
    for _node, _cost in dist_dict[node].items() :
      if _node != node :
        next_cost = cost + _cost
        if dist_list[_node] > next_cost :
          heappush(q, (next_cost, _node))
  
  print(dist_list[-1] if dist_list[-1] < MAX else 'Impossible')

except :
  print('Impossible')

 

풀이 완료!

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.