백준 18405번 - 경쟁적 전염
경쟁적 전염 문제 바로 가기
풀이 날짜: 2026-01-08
baekjoon 알고리즘 문제 풀이
풀이 코드
import sys
input = sys.stdin.readline
from collections import deque
dx = [0,0,-1,1]
dy = [-1,1,0,0]
n,k = map(int, input().split())
graph = []
data = []
for i in range(n):
graph.append(list(map(int, input().split())))
for j in range(n):
if graph[i][j] != 0:
data.append((graph[i][j],0,i,j)) #바이러스 종류, 시간, 위치x, 위치y
data.sort()
q = deque(data)
targetS,targetX,targetY = map(int, input().split())
while q:
virus,s,x,y = q.popleft()
if s == targetS:
break
for i in range(4):
nx = dx[i] + x
ny = dy[i] + y
if 0<=nx<n and 0<=ny<n and graph[nx][ny] == 0:
graph[nx][ny] = virus
q.append((virus,s+1,nx,ny))
print(graph[targetX-1][targetY-1])
문제 핵심 요약:
단순 BFS가 아닌, 바이러스 번호가 작은 것이 항상 먼저 퍼져야 한다는 조건을 기억해두자.
- 초기 바이러스들을 번호 기준으로 정렬해서 큐에 넣기
- 큐에는 (virus,time,x,y) 형태로 넣고 BFS
- BFS는 time이 증가하면서 퍼지고
- 같은 time 안에서는 큐에 들어간 순서가 유지되므로, 정렬한 순서가 그대로 우선순위를 만든다.
내가 선택한 풀이 방식
1) 입력에서 ‘초기 바이러스 위치’를 모두 수집
- 처음부터 여러 종류의 바이러스가 동시에 존재하므로, BFS의 시작점이 1개가 아니라 여러 개다.
- 따라서 그 시작점들을 정렬해서 큐에 넣는 게 핵심이다.
2) 번호 순서 보장을 위해 초기 목록을 정렬
- 정렬을 하면 virus 번호가 오름차순으로 들어가므로 0초에 퍼질 순서가 정확해진다.
- BFS가 진행될 때도 “1초에 새로 감염된 것들”은 큐 뒤로 들어가면서 같은 시간대 내에서도 번호 우선이 유지된다.
시간 관리 방식
- 일반 BFS는 “level”로 시간을 관리할 수도 있지만 이 코드는 튜플에 s를 넣어서 명시적으로 관리했다.
- q.append((virus, s+1, nx, ny))
break로 조기 종료
- BFS 특성상 큐에서 꺼내는 순서는 시간이 증가하는 방향
- 처음으로 targetS 시간에 도달한 순간 이후는 의미가 없다.
(X,Y) 1-index → 0-index 변환
- 출력에서 -1 빠뜨리면 바로 틀림.