#include <iostream>
#include <vector>
using namespace std;
class DSU{
public:
vector<int>parent;
DSU(int n)
{
parent = vector<int>(n);
for(int i = 0; i< n; ++i)
{
parent[i] = i;
}
}
int Find(int x)
{
if(parent[x] != x)parent[x] = Find(parent[x]);
return parent[x];
}
void Union(int x, int y)
{
parent[Find(x)] = Find(y);
}
};
int findCircleNums(const vector<vector<int>>& M)
{
DSU dsu(M.size());
for(int i = 0; i < M.size(); ++i)
{
for(int j = 0; j < M[0].size(); ++j)
{
if(M[i][j] == 1)dsu.Union(i,j);
}
}
int res = 0;
for(int i = 0; i < M.size(); ++i)
{
if(dsu.Find(i) == i) ++res;
}
return res;
}
vector<vector<int>>dirs{{0,1},{0,-1},{1,0},{-1,0}};
vector<int> numIslands(int m, int n, const vector<vector<int>>& position)
{
DSU dsu(m * n);
vector<vector<bool>>island(m,vector<bool>(n,false));
vector<int>res;
int cnt = 0;
for(auto cur:position)
{
if(island[cur[0]][cur[1]])
{
res.push_back(cnt);
continue;
}
island[cur[0]][cur[1]] = true;
++cnt;
for(auto dir:dirs)
{
int x = cur[0] + dir[0],y = cur[1] + dir[1];
if(x < 0 || x >= m || y < 0 || y >= n || island[x][y] == false)continue;
int compoent1 = dsu.Find(cur[0] * n + cur[1]);
int compoent2 = dsu.Find(x * n + y);
if(compoent1 != compoent2)
{
dsu.Union(compoent1,compoent2);
--cnt;
}
}
res.push_back(cnt);
}
return res;
}
int main()
{
//LeetCode547
vector<vector<int>>nums{{1,1,0},{1,1,0},{0,0,1}};
cout << findCircleNums(nums) << endl;
//LeetCode305
vector<vector<int>>islands{{0,0},{0,1},{1,2},{2,1}};
auto res = numIslands(3,3,islands);
for(int num:res)
{
cout << num << " ";
}
cout << endl;
return 0;
}