ps | |
---|---|
링크 | programmers.co.kr/… |
출처 | 프로그래머스 |
문제 번호 | 81304 |
문제명 | 미로 탈출 |
레벨 | Level 4 |
분류 |
다익스트라 |
시간복잡도 | O(E*T*2^T*logV) |
인풋사이즈 | V<=1000, E<=3000, T<=10 |
사용한 언어 | Python |
해결날짜 | 2021/07/10 |
출처 |
ps:problems:programmers:2021_카카오_채용연계형_인턴십 |
"""Solution code for "Programmers 81304. 미로 탈출".
- Problem link: https://programmers.co.kr/learn/courses/30/lessons/81304
- Solution link: http://www.teferi.net/ps/problems/programmers/81304
"""
import heapq
INF = float('inf')
def dijkstra(next_states_and_dists,
source: int,
is_sink_state) -> float:
distances = {source: 0}
heap = [(0, source)]
while heap:
dist_u, u = heapq.heappop(heap)
if dist_u != distances[u]:
continue
if is_sink_state(u):
return dist_u
for v, dist_uv in next_states_and_dists(u):
dist_v = dist_u + dist_uv
if dist_v < distances.get(v, INF):
distances[v] = dist_v
heapq.heappush(heap, (dist_v, v))
raise ValueError
def solution(n, start, end, roads, traps):
def is_trap_activated(trap_state, node):
return node in trap_bit and (trap_state & trap_bit[node]) != 0
def flip_trap(trap_state, node):
return (trap_state ^ trap_bit[node]) if node in trap_bit else trap_state
def next_states_and_dists(state):
u, trap_state = state
is_cur_node_activated = is_trap_activated(trap_state, u)
for v, dist in edges_from[u]:
if is_cur_node_activated == is_trap_activated(trap_state, v):
yield (v, flip_trap(trap_state, v)), dist
for v, dist in edges_to[u]:
if is_cur_node_activated != is_trap_activated(trap_state, v):
yield (v, flip_trap(trap_state, v)), dist
trap_bit = {trap - 1: (1 << i) for i, trap in enumerate(traps)}
edges_from = [[] for _ in range(n)]
edges_to = [[] for _ in range(n)]
for u, v, dist in roads:
edges_from[u - 1].append((v - 1, dist))
edges_to[v - 1].append((u - 1, dist))
return dijkstra(next_states_and_dists,
(start - 1, 0),
lambda state: state[0] == end - 1)