public: intlatestDayToCross(int row, int col, vector<vector<int>>& cells){ int left = 0, right = row * col, ans = 0; while (left <= right) { int mid = (left + right) / 2; vector<vector<int>> grid(row, vector<int>(col, 1)); for (int i = 0; i < mid; ++i) { grid[cells[i][0] - 1][cells[i][1] - 1] = 0; }
queue<pair<int, int>> q; for (int i = 0; i < col; ++i) { if (grid[0][i]) { q.emplace(0, i); grid[0][i] = 0; } } bool found = false; while (!q.empty()) { auto [x, y] = q.front(); q.pop(); for (int d = 0; d < 4; ++d) { int nx = x + dirs[d][0]; int ny = y + dirs[d][1]; if (nx >= 0 && nx < row && ny >= 0 && ny < col && grid[nx][ny]) { if (nx == row - 1) { found = true; break; } q.emplace(nx, ny); grid[nx][ny] = 0; } } } if (found) { ans = mid; left = mid + 1; } else { right = mid - 1; } } return ans; } };
classSolution: deflatestDayToCross(self, row: int, col: int, cells: List[List[int]]) -> int: left, right, ans = 0, row * col, 0 while left <= right: mid = (left + right) // 2 grid = [[1] * col for _ inrange(row)] for x, y in cells[:mid]: grid[x - 1][y - 1] = 0
q = deque() for i inrange(col): if grid[0][i]: q.append((0, i)) grid[0][i] = 0 found = False while q: x, y = q.popleft() for nx, ny in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]: if0 <= nx < row and0 <= ny < col and grid[nx][ny]: if nx == row - 1: found = True break q.append((nx, ny)) grid[nx][ny] = 0 if found: ans = mid left = mid + 1 else: right = mid - 1 return ans
// 并查集模板 classUnionFind { public: vector<int> parent; vector<int> size; int n; // 当前连通分量数目 int setCount; public: UnionFind(int _n): n(_n), setCount(_n), parent(_n), size(_n, 1) { iota(parent.begin(), parent.end(), 0); } intfindset(int x){ return parent[x] == x ? x : parent[x] = findset(parent[x]); } boolunite(int x, int y){ x = findset(x); y = findset(y); if (x == y) { returnfalse; } if (size[x] < size[y]) { swap(x, y); } parent[y] = x; size[x] += size[y]; --setCount; returntrue; } boolconnected(int x, int y){ x = findset(x); y = findset(y); return x == y; } };
classSolution { public: intlatestDayToCross(int row, int col, vector<vector<int>>& cells){ // 编号为 n 的节点是超级节点 s // 编号为 n+1 的节点是超级节点 t int n = row * col; auto uf = UnionFind(n + 2);
vector<vector<int>> valid(row, vector<int>(col)); int ans = 0; for (int i = n - 1; i >= 0; --i) { int x = cells[i][0] - 1, y = cells[i][1] - 1; valid[x][y] = true; // 并查集是一维的,(x, y) 坐标是二维的,需要进行转换 int id = x * col + y; if (x - 1 >= 0 && valid[x - 1][y]) { uf.unite(id, id - col); } if (x + 1 < row && valid[x + 1][y]) { uf.unite(id, id + col); } if (y - 1 >= 0 && valid[x][y - 1]) { uf.unite(id, id - 1); } if (y + 1 < col && valid[x][y + 1]) { uf.unite(id, id + 1); } if (x == 0) { uf.unite(id, n); } if (x == row - 1) { uf.unite(id, n + 1); } if (uf.connected(n, n + 1)) { ans = i; break; } } return ans; } };
# 并查集模板 classUnionFind: def__init__(self, n: int): self.parent = list(range(n)) self.size = [1] * n self.n = n # 当前连通分量数目 self.setCount = n deffindset(self, x: int) -> int: if self.parent[x] == x: return x self.parent[x] = self.findset(self.parent[x]) return self.parent[x] defunite(self, x: int, y: int) -> bool: x, y = self.findset(x), self.findset(y) if x == y: returnFalse if self.size[x] < self.size[y]: x, y = y, x self.parent[y] = x self.size[x] += self.size[y] self.setCount -= 1 returnTrue defconnected(self, x: int, y: int) -> bool: x, y = self.findset(x), self.findset(y) return x == y
classSolution: deflatestDayToCross(self, row: int, col: int, cells: List[List[int]]) -> int: # 编号为 n 的节点是超级节点 s # 编号为 n+1 的节点是超级节点 t n = row * col uf = UnionFind(n + 2)
valid = [[0] * col for _ inrange(row)] ans = 0 for i inrange(n - 1, -1, -1): x, y = cells[i][0] - 1, cells[i][1] - 1 valid[x][y] = 1 # 并查集是一维的,(x, y) 坐标是二维的,需要进行转换 idx = x * col + y if x - 1 >= 0and valid[x - 1][y]: uf.unite(idx, idx - col) if x + 1 < row and valid[x + 1][y]: uf.unite(idx, idx + col) if y - 1 >= 0and valid[x][y - 1]: uf.unite(idx, idx - 1) if y + 1 < col and valid[x][y + 1]: uf.unite(idx, idx + 1) if x == 0: uf.unite(idx, n) if x == row - 1: uf.unite(idx, n + 1) if uf.connected(n, n + 1): ans = i break return ans