-
[BOJ/python] 2982번 국왕의 방문알고리즘/BOJ 2022. 6. 30. 17:56
2982번 국왕의 방문 파이썬
출처 - https://www.acmicpc.net/problem/2982
로직은 쉽게 생각할 수 있는 다익스트라 문제였다. 다만 국왕이 도로를 점유하고 있는 상황을 표현하는 방법이 조금 까다로웠다. 메모리를 비효율적으로 사용하더라도 우선 풀어야겠다고 생각했다. 인접 행렬과 인접 리스트를 모두 사용하여 국왕의 위치를 표시했다.
1. 풀이
- path[u][v]에 u에서 v로 국왕이 이동을 시작한 시간, 도착한 시간을 저장한다. 양방향 그래프이므로 방향과 관계 없이 path[u][v], path[v][u]를 똑같은 값으로 저장한다.
- 다익스트라에서 출발 지점의 초기 거리값을 K로 갱신하여 국왕이 이동하는 시간과 동기화할 수 있다. 이후 도착 시간에서 K를 빼면 이동 시간을 구할 수 있다.
- 다익스트라를 수행하며 현재 노드(node), 다음 노드(next) 사이를 국왕이 지나간 시간을 확인한다. path[node][next] = 출발시간, 도착시간
- 만약 내가 node에 도착한 시간이 출발시간과 도착시간 사이에 있다면 나의 출발 시간을 국왕의 도착시간으로 갱신한다.
- 다익스트라가 종료되면 B에 도착한 최소 시간에서 출발 시간인 K를 빼고 출력한다.
2. 코드
# boj-2982.py from heapq import heappop, heappush N,M = map(int, input().split()) A,B,K,G = map(int, input().split()) king = list(map(int, input().split())) graph = [ [] for _ in range(N+1) ] graph2= [ [0 for _ in range(N+1)] for _ in range(N+1) ] for _ in range(M): u,v,w = map(int, input().split()) graph[u].append([v,w]) graph[v].append([u,w]) graph2[u][v] = w graph2[v][u] = w path = [ [ [-1,-1] for _ in range(N+1)] for _ in range(N+1) ] time = 0 for i in range(1, G): before = king[i-1] node = king[i] path[before][node] = time, time + graph2[before][node] path[node][before] = time, time + graph2[before][node] time += graph2[before][node] dist = [float('inf') for _ in range(N+1)] dist[A]=K heap = [[K,A]] while heap: cost, node = heappop(heap) if dist[node] < cost : continue for next, weight in graph[node]: my_start= cost king_start, king_end = path[node][next] if king_start<=my_start<=king_end : my_start = king_end if dist[next] > my_start+weight : dist[next] = my_start+weight heappush(heap, [dist[next], next]) print(dist[B]-K)
2.2 코드(오답)
아래와 같이 인접 리스트만 이용하여 풀었지만 51퍼센트에서 틀렸다. 왜 그런지 아직도 모르겠다.
# boj-2982.py from heapq import heappop, heappush N,M = map(int, input().split()) A,B,K,G = map(int, input().split()) king = list(map(int, input().split())) graph = [ [] for _ in range(N+1) ] for _ in range(M): u,v,w = map(int, input().split()) graph[u].append([v,w]) graph[v].append([u,w]) path = [[-1,-1]for _ in range(N+1)] if G>=1: path[king[0]] = [0,0] time = 0 for i in range(1, len(king)): node = king[i] before = king[i-1] for next, cost in graph[before]: if next== node: time += cost #어디서 왔는지?, 여기서 다시 출발 시간 언제야? (여기 도착시간) path[node] = [before, time] break dist = [float('inf') for _ in range(N+1)] dist[A]=K heap = [[K,A]] while heap: cost, node = heappop(heap) if dist[node] < cost : continue for next, weight in graph[node]: my_start,my_end = cost, cost+weight #내 출발 지점과 왕 출발지점 같을 때 if path[next][0] ==node : king_start, king_end = path[node][1], path[next][1] if king_start<=my_start<king_end : my_start = king_end #내 출발지점과 왕의 도착 지점이 같을 때 elif path[node][0] ==next: king_start, king_end = path[next][1], path[node][1] if king_start<=my_start<king_end: my_start = king_end if dist[next] > my_start+weight : dist[next] = my_start+weight heappush(heap, [dist[next], next]) print(dist[B]-K)
'알고리즘 > BOJ' 카테고리의 다른 글
[BOJ/python]1765번 닭싸움 팀 정하기 (0) 2022.07.03 [BOJ/python] 6987번 월드컵 (0) 2022.07.01 [BOJ/python] 2412번 암벽 등반 (0) 2022.07.01 [BOJ/python]2263번 트리의 순회 (0) 2022.06.29 [BOJ/python] 2623번 음악프로그램 (0) 2022.06.29