import copy from collections import deque from typing importList
DIRS = [(0, 1), (0, -1), (-1, 0), (1, 0)]
classSolution: defmaximumMinutes(self, grid: List[List[int]]) -> int: n, m = len(grid), len(grid[0])
l, r = 0, n * m
defcheck(s: int) -> bool: u = copy.deepcopy(grid) q = deque() for i inrange(n): for j inrange(m): if u[i][j] == 1: q.append((i, j)) while s > 0: le = len(q) while le > 0: poll = q.popleft() x, y = poll[0], poll[1] for dx, dy in DIRS: xx, yy = x + dx, y + dy if n > xx >= 0and m > yy >= 0and u[xx][yy] == 0: u[xx][yy] = 1 q.append((xx, yy)) le -= 1 s -= 1 if u[0][0] == 1or u[n - 1][m - 1] == 1: returnFalse q2 = deque() q2.append((0, 0)) vis = [[0] * m for _ inrange(n)] vis[0][0] = 1 while q2: sz2 = len(q) flag = False while sz2: poll = q.popleft() x, y = poll[0], poll[1] for dx, dy in DIRS: xx, yy = x + dx, y + dy if n > xx >= 0and m > yy >= 0and u[xx][yy] == 0: u[xx][yy] = 1 if xx == n - 1and yy == m - 1: flag = True q.append((xx, yy)) sz2 -= 1 sz1 = len(q2) while sz1: poll = q2.popleft() x, y = poll[0], poll[1] if x == n - 1and y == m - 1: returnTrue for dx, dy in DIRS: xx, yy = x + dx, y + dy if n > xx >= 0and m > yy >= 0and ( u[xx][yy] == 0or xx == n - 1and yy == m - 1and flag) andnot vis[xx][yy]: q2.append((xx, yy)) vis[xx][yy] = 1 sz1 -= 1 returnFalse
while l < r: mid = (l + r + 1) // 2 if check(mid): l = mid else: r = mid - 1 if l == m * n: return10 ** 9 else: return l if check(l) else -1
解法二
O(nm)做法,单源BFS(人)+多源BFS(火),计算出每个位置被人或者是火最早到达的时间分别为g1、g2,一个简单的设想,假设人可以到达安全位置(n - 1, m - 1)的话,那么答案为g2[n−1][m−1]−g1[n−1][m−1],但是这个答案是我们理想状态下的,并且是题目恰好有一个条件就是可以在安全位置允许火和人同时到达,但在这种情况下无法保证其他的可以到达的点都是人先到然后火后到,又由于(n−1,m−1)是由(n−2,m−1)或者(n−1,m−2)而转移来的,那么只需要保证在对于这两个转移点进行判断时,存在其一g2[x][y]−g1[x][y]>(g2[n−1][m−1]−g1[n−1][m−1])就可以保证答案为最理想的结果,否则则减一,减一一定可以保证人先到,火后到。