disjoint set is designed to solve union-find problem.

It is very fast when applied with path compression.

```
class Solution {
public:
int findCircleNum(vector<vector<int>>& M) {
int N = M.size();
if (N == 0)
return 0;
d.resize(N);
for (int i = 0; i < N; ++i)
d[i] = i;
for (int i = 0; i < N; ++i)
for (int j = i+1; j < N; ++j)
if (M[i][j] == 1)
merge(i, j);
int count = 0;
for (int i = 0; i < N; ++i)
if (i == d[i])
count ++;
return count;
}
void merge(int i, int j)
{
d[parent(i)] = parent(j);
}
int parent(int x)
{
if (d[x] == x)
return x;
return d[x] = parent(d[x]); // path compression
}
vector<int> d; // disjoint set
};
```