[파이썬] 백준 17142번 연구소 3

작성:

백준 #17142 연구소 3


# NxN 정사각형 연구소
# 빈칸, 벽, 바이러스로 이루어져있다
# 활성 바이러스가 비활성 바이러스로 가면 비활성이 활성으로 변한다

# 출력: 모든 빈 칸에 바이러스가 있게 되는 최소 시간
    # 모든 빈 칸에 바이러스를 놓을 수 없으면 -1 출력

# N이 최대 50이므로 맵 전체를 탐색한다면 2500번,
# 2의 개수는 10보다 작거나 같으므로 대략 10C5정도가 가장 큰 경우의 수
# 10C5 * 2500 * 5 = 315만
# 가지치기 해서 풀어보자

from collections import deque
from itertools import combinations

def BFS(candis, min_time, left):
    global time
    q = deque(candis)
    time_val = 0
    visited = [[0 for i in range(N)] for j in range(N)]
    for y, x in candis:
        visited[y][x] = 1

    while q:
        if not left: break
        time_val += 1
        if time_val >= min_time: return float('inf')
        for i in range(len(q)):
            y, x = q.popleft()

            for j in range(4):
                ny = y + dy[j]
                nx = x + dx[j]

                if 0 <= ny < N and 0 <= nx < N and field[ny][nx] != 1 \
                and not visited[ny][nx]:
                    visited[ny][nx] = 1
                    q.append((ny, nx))
                    if field[ny][nx] == 0: 
                        left -= 1
    
    if not left: return time_val   
    else: return float('inf')     

N, M = map(int, input().split())
field = [list(map(int, input().split())) for i in range(N)]
virus_candis = []
dy = [0, 1, 0, -1]
dx = [1, 0, -1, 0]
time = float('inf')
left = 0

for i in range(N):
    for j in range(N):
        if field[i][j] == 2:
            virus_candis.append((i, j))
        if field[i][j] == 0:
            left += 1

for candi in combinations(virus_candis, M):
    time = min(time, BFS(candi, time, left))

if time == float('inf'): time = -1

print(time)

댓글남기기