|
1 |
| -# Runtime: 170 ms (Top 85.91%) | Memory: 15.7 MB (Top 23.94%) |
| 1 | +// Runtime: 70 ms (Top 98.46%) | Memory: 18.30 MB (Top 33.85%) |
| 2 | + |
2 | 3 | class Solution:
|
3 | 4 | def minDays(self, grid: List[List[int]]) -> int:
|
4 |
| - cnt = 0 |
5 |
| - for i in range(len(grid)): |
6 |
| - for j in range(len(grid[0])): |
7 |
| - if grid[i][j]: |
8 |
| - cnt += 1 # count the number of elements |
9 |
| - root = (i, j) # assign the root node for the graph |
10 |
| - |
11 |
| - if cnt <= 1 : return cnt # no elements in the map |
12 |
| - |
13 |
| - vis, low, time, res = {root}, {}, {}, [] |
14 |
| - |
15 |
| - # find whether articulation points are present in the matrix |
16 |
| - def articulation_points(curr, parent): |
17 |
| - low[curr] = time[curr] = len(vis) |
18 |
| - children = 0 |
19 |
| - i, j = curr |
20 |
| - |
21 |
| - for x, y in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]: |
22 |
| - if (x, y) == parent : continue |
23 |
| - |
24 |
| - if 0<=x<len(grid) and 0<=y<len(grid[0]) and grid[x][y]: |
25 |
| - if (x, y) not in vis: |
26 |
| - vis.add((x,y)) |
27 |
| - articulation_points((x,y), curr) |
28 |
| - low[curr] = min(low[curr], low[(x, y)]) |
29 |
| - children += 1 |
30 |
| - if low[(x, y)] >= time[(curr)] and parent!=(-1, -1): |
31 |
| - res.append([i, j]) |
32 |
| - else: |
33 |
| - low[curr] = min(low[curr], time[(x, y)]) |
34 |
| - |
35 |
| - if parent == (-1, -1) and children > 1: |
36 |
| - res.append([x, y]) |
37 |
| - |
38 |
| - articulation_points(root, (-1, -1)) |
39 |
| - |
40 |
| - if len(vis) != cnt: # if the matrix is disconnected beforehand |
| 5 | + rows, cols = len(grid), len(grid[0]) |
| 6 | + |
| 7 | + disc_time = [[-1 for _ in range(cols)] for _ in range(rows)] |
| 8 | + low_value = [[-1 for _ in range(cols)] for _ in range(rows)] |
| 9 | + parents = [[(-1, -1) for _ in range(cols)] for _ in range(rows)] |
| 10 | + is_ap = [[False for _ in range(cols)] for _ in range(rows)] |
| 11 | + dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)] |
| 12 | + |
| 13 | + time = 0 |
| 14 | + has_ap = False |
| 15 | + def dfs(i, j): |
| 16 | + if grid[i][j] == 0: |
| 17 | + return |
| 18 | + nonlocal time |
| 19 | + nonlocal has_ap |
| 20 | + disc_time[i][j] = time |
| 21 | + low_value[i][j] = time |
| 22 | + time += 1 |
| 23 | + |
| 24 | + child = 0 |
| 25 | + for di, dj in dirs: |
| 26 | + ni, nj = i + di, j + dj |
| 27 | + if not (0 <= ni < rows) or not (0 <= nj < cols): |
| 28 | + continue |
| 29 | + if grid[ni][nj] != 1: |
| 30 | + continue |
| 31 | + |
| 32 | + if disc_time[ni][nj] == -1: # not visited |
| 33 | + child += 1 |
| 34 | + parents[ni][nj] = (i, j) |
| 35 | + dfs(ni, nj) |
| 36 | + low_value[i][j] = min(low_value[i][j], low_value[ni][nj]) |
| 37 | + |
| 38 | + if parents[i][j] == (-1, -1) and child > 1: |
| 39 | + is_ap[i][j] = True |
| 40 | + has_ap = True |
| 41 | + |
| 42 | + if parents[i][j] != (-1, -1) and low_value[ni][nj] >= disc_time[i][j]: |
| 43 | + is_ap[i][j] = True |
| 44 | + has_ap = True |
| 45 | + elif (ni, nj) != parents[i][j]: |
| 46 | + low_value[i][j] = min(low_value[i][j], disc_time[ni][nj]) |
| 47 | + |
| 48 | + sccs = 0 |
| 49 | + num_ones = 0 |
| 50 | + for i in range(rows): |
| 51 | + for j in range(cols): |
| 52 | + if grid[i][j] == 1: |
| 53 | + num_ones += 1 |
| 54 | + if disc_time[i][j] == -1 and grid[i][j] == 1: |
| 55 | + dfs(i, j) |
| 56 | + sccs += 1 |
| 57 | + |
| 58 | + |
| 59 | + if sccs > 1: |
41 | 60 | return 0
|
42 |
| - elif res: # if there are any articulation points |
| 61 | + elif has_ap: |
43 | 62 | return 1
|
44 |
| - else: # worst case, no articulation points |
45 |
| - return 2 |
| 63 | + else: |
| 64 | + if num_ones == 1: |
| 65 | + return 1 |
| 66 | + elif num_ones == 0: |
| 67 | + return 0 |
| 68 | + return 2 |
| 69 | + |
| 70 | + |
0 commit comments