LeetCode -- 827. 最大人工岛
题目大意:给一个邻接矩阵,问改变一个点后,最大连通块多大
对于这种连通块相关问题,一般的思路就是进行深搜和并查集,这里采用并查集维护连通块大小解法。
首先先初始化并查集,并进行连通块的合并;再对图中的0进行枚举,找到最大的连通块即可。
对(n * m)的二维点阵图常用技巧,二维转一维:点(i, j)对应的一维节点:i * m + j。
class Solution { public: int n, m; vector<int> p, sz; int find(int x) { if(x != p[x]) p[x] = find(p[x]); return p[x]; } int get(int i, int j) { return i * m + j; } int dx[4] = {-1, 0, 1, 0}; int dy[4] = {0, 1, 0, -1}; int largestIsland(vector<vector<int>>& grid) { n = grid.size(), m = grid[0].size(); for(int i = 0; i < n * m; i ++ ) { p.push_back(i); sz.push_back(1); } int res = 1; for(int i = 0; i < n; i ++ ) { for(int j = 0; j < m; j ++ ) { if(grid[i][j]) { int a = get(i, j); for(int k = 0; k < 4; k ++ ) { int nx = i + dx[k], ny = j + dy[k]; if(nx < 0 || nx >= n || ny < 0 || ny >= m || !grid[nx][ny]) continue; int b = get(nx, ny); if(find(a) != find(b)) { sz[find(b)] += sz[find(a)]; p[find(a)] = find(b); } } res = max(res, sz[find(a)]); } } } for(int i = 0; i < n; i ++ ) { for(int j = 0; j < m; j ++ ) { if(!grid[i][j]) { map<int, int> mp; for(int k = 0; k < 4; k ++ ) { int nx = i + dx[k], ny = j + dy[k]; if(nx < 0 || nx >= n || ny < 0 || ny >= m || grid[nx][ny]) continue; int a = get(nx, ny); mp[find(a)] = sz[find(a)]; } int s = 1; for(auto &[k, v]: mp) { s += v; } res = max(res, s); } } } return res; } };