-
[BOJ/python] 2982번 국왕의 방문알고리즘/BOJ 2022. 6. 30. 17:56
2982번 국왕의 방문 파이썬
출처 - https://www.acmicpc.net/problem/2982
2982번: 국왕의 방문
지난주에 상그니 아라비아의 국왕 고둘라 창지즈 영사우드가 한국에 도착했다. 고둘라는 매우 중요한 사람이다. 따라서, 경찰은 그가 타고 있는 차량이 길에 진입했을 때, 그가 길에 있는 동안
www.acmicpc.net
로직은 쉽게 생각할 수 있는 다익스트라 문제였다. 다만 국왕이 도로를 점유하고 있는 상황을 표현하는 방법이 조금 까다로웠다. 메모리를 비효율적으로 사용하더라도 우선 풀어야겠다고 생각했다. 인접 행렬과 인접 리스트를 모두 사용하여 국왕의 위치를 표시했다.
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