1970. 你能穿过矩阵的最后一天
2021.8.16
题解
class Solution {
private:
vector<int> fa;
int findset(int x) { return x == fa[x] ? x : fa[x] = findset(fa[x]); }
void unite(int x, int y) { fa[findset(x)] = findset(y); }
bool connected(int x, int y) { return findset(x) == findset(y); }
public:
int latestDayToCross(int row, int col, vector<vector<int>>& cells) {
int ans = 0;
int n = row * col;
fa.resize(n + 2);
iota(fa.begin(), fa.end(), 0);
vector<int> valid(n + 2);
for (int i = n - 1; i >= 0; --i) {
int x = cells[i][0] - 1, y = cells[i][1] - 1;
int id = x * col + y;
valid[id] = true;
if (x - 1 >= 0 && valid[id - col]) unite(id, id - col);
if (x + 1 < row && valid[id + col]) unite(id, id + col);
if (y - 1 >= 0 && valid[id - 1]) unite(id, id - 1);
if (y + 1 < col && valid[id + 1]) unite(id, id + 1);
if (x == 0) unite(id, n);
if (x == row - 1) unite(id, n + 1);
if (connected(n, n + 1)) { ans = i; break; }
}
return ans;
}
};
并查集模板
class UnionFind {
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);
}
int findset(int x) {
return parent[x] == x ? x : parent[x] = findset(parent[x]);
}
bool unite(int x, int y) {
x = findset(x);
y = findset(y);
if (x == y) {
return false;
}
if (size[x] < size[y]) {
swap(x, y);
}
parent[y] = x;
size[x] += size[y];
--setCount;
return true;
}
bool connected(int x, int y) {
x = findset(x);
y = findset(y);
return x == y;
}
};