Algorithm/acmicpc.net
0-1 BFS를 처음 성공한 날.
winney916
2022. 2. 5. 12:03
728x90
저번 포스팅 중에서 0-1 BFS를 공부할 필요가 있다고 했었다.
근데 오늘 자연스럽게 해버림
#1261 알고스팟 https://www.acmicpc.net/problem/1261
1261번: 알고스팟
첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미
www.acmicpc.net
처음엔 그냥 DP를 사용한 BFS로 풀이했다.
N, M = map(int, input().split())
way = [[int(x) for x in input()] for _ in range(M)]
visited = [[-1 for _ in range(N)] for __ in range(M)]
dx = [1, 0, ]
dy = [0, 1, ]
que = [[0, 0]]
visited[0][0] = 0
while que:
x, y = que.pop(0)
walls = visited[x][y]
for i in range(2):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < M and 0 <= ny < N:
# print(nx, ny)
if visited[nx][ny] == -1:
visited[nx][ny] = walls + way[nx][ny]
que.append([nx, ny])
else:
visited[nx][ny] = min(walls + way[nx][ny], visited[nx][ny])
que.append([nx, ny])
print(visited[M-1][N-1])
틀리는 이유를 알 수 없었다.
구글링 결과
문제는 역시 가중치의 차이에서 발생했다.
1인 노드에서는 1을 더해주고
0인 노드에서는 0을 더해준다.
때문에 같은 길이였어도 가중치가 1인 노드를 지나온 경로가 더욱 큰 값을 갖는다.
나는 이를 처리하기 위해 min을 적용했었다.
근데 필요없었다.
가중치가 더 작은 노드를 지나는 경로라면
BFS탐색의 que에서 leftappend를 해주면 된다.
즉 가중치가 0인 노드를 만날 경우를 우선해서 연산하는 것이다.
이를 0-1 BFS라고 한다.
수정 후 시간초과가 나지 않은 코드
M, N = map(int, input().split())
way = []
for i in range(N):
way.append(list(map(int, input())))
visited = [[-1]*M for i in range(N)]
# 상하좌우 탐색
dx = [1, 0, 0, -1]
dy = [0, 1, -1, 0]
que = [[0, 0]]
visited[0][0] = 0
while que:
x, y = que.pop(0)
walls = visited[x][y]
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < N and 0 <= ny < M:
# print(nx, ny)
if visited[nx][ny] == -1:
if way[nx][ny] == 0: #가중치가 0인 경우
visited[nx][ny] = walls + way[nx][ny]
# left append
que = [[nx, ny]] + que
else: # 가중치가 0이 아닌경우 (1인경우)
visited[nx][ny] = walls + way[nx][ny]
# right append
que.append([nx, ny])
print(visited[N-1][M-1])
배운게 많은 문제였다.