크기의 상자에 토마토가 보관되어 있습니다. 1은 익은 토마토, 0은 익지 않은 토마토, -1은 빈 칸을 의미합니다. 익은 토마토의 상하좌우에 있는 익지 않은 토마토는 하루가 지나면 익게 됩니다. 토마토가 혼자 저절로 익는 경우는 없다고 할 때, 상자 안의 모든 토마토가 익을 때까지 걸리는 최소 일수를 구하는 문제입니다.
이 문제는 최단 거리를 구하는 미로 탐색 문제와 유사하지만, 가장 큰 차이점은 시작점(익은 토마토)이 여러 개일 수 있다는 것입니다. 이를 해결하기 위해 '다중 시작점 BFS' 기법을 사용해야 합니다.
bfs() 함수를 호출하기 전에, 이중 for문으로 상자를 훑으며 모든 1의 좌표를 먼저 queue에 담아두어야 합니다.0)를 발견하면, 해당 위치의 값을 graph[nx][ny] = graph[x][y] + 1 로 갱신합니다. 이렇게 하면 별도의 visited 배열 없이도 방문 처리가 될 뿐만 아니라, 며칠이 지났는지 자동으로 누적 기록됩니다.0이 하나라도 남아있다면 토마토가 모두 익지 못한 것이므로 -1을 출력합니다.import sys
from collections import deque
input = sys.stdin.readline
M, N = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(N)]
queue = deque()
# 1. 맵 전체를 돌며 익은 토마토(1)를 모두 큐에 담기
for i in range(N):
for j in range(M):
if graph[i][j] == 1:
queue.append((i, j))
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs():
while queue:
x, y = queue.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
# 2. 범위를 벗어나지 않고, 안 익은 토마토(0)라면
if 0 <= nx < N and 0 <= ny < M and graph[nx][ny] == 0:
queue.append((nx, ny))
# 3. 일수 누적 기록
graph[nx][ny] = graph[x][y] + 1
bfs()
result = 0
# 4. 탐색 종료 후 검증
for row in graph:
# 안 익은 토마토가 존재하면 -1 출력 후 즉시 종료
if 0 in row:
print(-1)
exit(0)
# 가장 높은 값(가장 오래 걸린 일수) 갱신
result = max(result, max(row))
# 시작이 1이었으므로 1을 빼서 출력
print(result - 1)
max 함수의 활용: 2차원 리스트에서 최댓값을 찾을 때 max(map(max, graph))와 같은 방식을 쓸 수도 있지만, 이 문제에서는 0이 포함되어 있는지 검사하는 과정이 무조건 필요하므로 for row in graph:를 돌면서 if 0 in row:로 검사하고 result = max(result, max(row))로 동시에 최댓값을 갱신하는 방식이 훨씬 효율적이고 직관적이었습니다.