백준-1261-알고스팟
업데이트:
문제
풀이
문제조건 해석
(1, 1)부터 (N, M)까지 이동할 때 최소로 벽을 부수는 경우 찾기
- 빈 방은 자유롭게 이동 가능
- 벽은 부숴야만 이동 가능
- 벽을 부수면 빈 방이 된다
- 상하좌우로만 이동 가능
처음에는 BFS로 찾아보려 했으나 생각이 나지 않아 다익스트라를 적용했다. BFS에 우선순위 큐 적용해도 간단하게 풀이가 가능했다.꾸준함 블로그
알고리즘
다익스트라 알고리즘에서
- 빈 방에 대해서는 가중치를 0으로 하는 노드로,
- 벽이 있는 경우는 가중치가 1인 노드로,
- 인접한 노드는 상하좌우 방으로 생각하면 된다.
dist[n][m]
: (n, m) 노드까지의 최단경로, 인접 정점 순회시마다 업데이트한다.
$O(MN)$의 시간복잡도
코드
from sys import stdin
import heapq
input = stdin.readline
m, n =[int(_) for _ in input().rstrip().split()]
maze = []
for _ in range(n):
maze.append([int(x) for x in input().rstrip()])
MAX_DIST = 200
dist = [[MAX_DIST for _ in range(m)] for __ in range(n)]
dist[0][0] = 0
pq = [(0, (0, 0))]
while pq:
w, u = heapq.heappop(pq)
ui, uj = u
if ui == n-1 and uj == m-1:
print(dist[n-1][m-1])
break
if w > dist[ui][uj]: # 큐에 넣었던 경로보다 더 짧은 경로로 업데이트되었을 때
continue
for di, dj in [(0, -1), (-1, 0), (0, 1), (1, 0)]:
vi, vj = ui+di, uj+dj
if not (0<=vi<n and 0<=vj<m):
continue
if maze[vi][vj]: # 벽이 있으면
if dist[ui][uj]+1 < dist[vi][vj]:
dist[vi][vj] = dist[ui][uj]+1
heapq.heappush(pq, (dist[vi][vj], (vi, vj)))
else: # 벽이 없으면
if dist[ui][uj] < dist[vi][vj]:
dist[vi][vj] = dist[ui][uj]
heapq.heappush(pq, (dist[vi][vj], (vi, vj)))
예시 입력
6 6
001111
010000
001111
110001
결과 dist배열
[[0, 0, 1, 2, 2, 2],
[0, 1, 1, 1, 1, 1],
[0, 0, 1, 2, 2, 2],
[1, 1, 1, 1, 1, 2],
[1, 2, 2, 1, 2, 2],
[2, 1, 1, 1, 2, 2]]
배운점
- 다익스트라와 우선순위 큐를 적용한 BFS는 꽤 유사하다
- 문제를 잘 추상화해서 알고리즘 적용할 수 있어야 한다.
- 유사 문제
댓글남기기