사용한 알고리즘 / 자료구조
- 우선순위 큐 (heapq)
- 트리
- 다익스트라 알고리즘
접근한 방식
두 로봇 사이의 최단 거리를 계산해야 합니다.
일반적인 다익스트라 방식으로 접근했습니다.
단, 현재 사용한 경로에서 '가장 긴 경로'를 제외해야 하므로 두 로봇 사이의 최단 경로 정보를 저장해야 합니다.
배열을 사용해 이를 구현합니다.
- path: 접근 경로를 저장하는 리스트. index == 노드 번호, value == 출발지
- path_distance: 경로의 길이를 저장하는 리스트. index == 노드 번호, value == 경로의 길이.
다익스트라 연산을 끝마친 후 경로를 역추적합니다.
로봇1에서 로봇2까지의 거리를 계산한 뒤 , 가장 길었던 경로(worst_path)를 거리에서 제합니다.
어려웠던 점
다익스트라 연산을 하며 경로 역추적.
느낀 점
경로 역추적을 구현하는 데에 괜찮은 문제들입니다.
https://www.acmicpc.net/problem/9019
9019번: DSLR
네 개의 명령어 D, S, L, R 을 이용하는 간단한 계산기가 있다. 이 계산기에는 레지스터가 하나 있는데, 이 레지스터에는 0 이상 10,000 미만의 십진수를 저장할 수 있다. 각 명령어는 이 레지스터에
www.acmicpc.net
https://www.acmicpc.net/problem/13913
13913번: 숨바꼭질 4
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
풀이했을 당시의 백준 티어
2021-10-25, 골드 1
실행시간, 메모리, 언어
632ms, 69476kb, Python3
import sys
import heapq
# 1. 입력
# a. 노드의 갯수
# b. 로봇1의 좌표
# c. 로봇 2의 좌표
N, ROBOT_1, ROBOT_2 = map(int, sys.stdin.readline().split())
# 2. 선언
# 1) 다익스트라 연산을 위한 배열 선언
total_distance = [-1] * (N + 1) # -1로 초기화(INF대신)
total_distance[ROBOT_1] = 0 # 출발지 초기값을 0으로 선언.
# 2) 경로 역추적을 위한 배열 선언
path = [0] * (N + 1) # 경로를 저장할 배열 선언. index 가 정점 번호, value 가 '어디에서 왔는지'
path_distance = [0] * (N + 1) # 해당 경로를 사용할 때 '경로' 의 길이값.
# 2-1. 경로 입력
connections = [[] for _ in range(N + 1)] # 연결 리스트 선언
for _ in range(N - 1):
node1, node2, distance = map(int, sys.stdin.readline().split())
connections[node1].append((distance, node2)) # 방향성이 없는 간선이므로
connections[node2].append((distance, node1)) # node1, node2에 모두 삽입.
# 3. 연산
# 1) 다익스트라 연산을 위해 큐 선언.
priority_que = [(0, ROBOT_1)]
# 2) 다익스트라 연산 시작.
while priority_que: # 큐에 값이 남아있는 동안
# (1) 현재 좌표와 거리 확인.
current_distance, current_node = heapq.heappop(priority_que)
# a. 가지치기
# 내가 현재 확인하는 지점에 더 빨리 도착할 수 있는 방법이 존재한다면
if total_distance[current_node] < current_distance:
continue
# (2) 다음 지점 확인
for next_distance, next_node in connections[current_node]:
# a. 다음 지점까지의 거리.
distance_sum = current_distance + next_distance
# i) 가지치기.
# next_node 에 방문한 적이 있으며 (초기값이 아니며)
# 현재 방법보다 더 빨리 도착할 방법이 존재한다면
if total_distance[next_node] != -1 and total_distance[next_node] <= distance_sum:
continue
# b. 기록 및 큐에 삽입.
total_distance[next_node] = distance_sum # 시작지점으로부터의 거리.
path[next_node] = current_node # 경로 입력.
path_distance[next_node] = next_distance # 경로의 길이 입력.
heapq.heappush(priority_que, (distance_sum, next_node)) # 큐에 삽입.
# 3) 경로 찾기 연산
path_index = ROBOT_2 # 끝 지점에서부터 조회.
distance_total = total_distance[ROBOT_2] # 거리의 총합
worst_path = 0 # 가장 긴 길의 길이를 저장할 변수.
while path_index:
current_path_distance = path_distance[path_index] # 현재 지점으로 오는 데 사용한 경로가
if current_path_distance > worst_path: # 지금까지 조회했던 경로들보다 길다면
worst_path = current_path_distance # 갱신.
path_index = path[path_index] # 인덱스 번호 업데이트.
# 4. 출력
print(distance_total - worst_path)
'BOJ > BFS, DFS, 백트래킹' 카테고리의 다른 글
18352. 특정 거리의 도시 찾기 - 파이썬. BFS, 큐 (0) | 2022.10.13 |
---|---|
1726. 로봇 - BFS, 구현, 시뮬레이션 (3) | 2021.10.19 |
2468. 안전영역 - 파이썬. BFS (0) | 2021.09.17 |
1260. DFS와 BFS - 파이썬 (0) | 2021.09.16 |
9019. DSLR (BFS) (0) | 2021.09.14 |