//并查集
class UnionFind {
public:
vector<int> parent;//记录父节点
int cnt;//连通分量
UnionFind(int n) {
this->cnt = n;
this->parent.resize(n);
for (int i = 0; i < n; ++i) {
parent[i] = i;//初始父节点指向自己
}
}
//找到x的根节点//根节点存在parent[x] = x,自己指向自身
int Find(int x) {
while (parent[x] != x) {
x = parent[x];
}
return x;
}
//连接p和q
void Union(int p, int q) {
int rootp = Find(p);//返回p的根节点
int rootq = Find(q);
if (rootp == rootq)//如果两者根节点相同,则在同一个集合里面,跳过
return ;
//根节点不同,但是由于p,q为连接的,故将p的集合作为子节点连接在q下面:rootp->rootq
parent[rootp] = rootq;
cnt--;
}
//返回连通分量
int Connect() {
return cnt;
}
};
class Solution {
public:
int citys(vector<vector<int> >& m) {
// write code here
int n = m.size();
if (n == 1)
return 1;
UnionFind uf(n);
//遍历邻接矩阵
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i == j)
continue;
if (m[i][j] == 1)
uf.Union(i, j);
}
}
return uf.Connect();
}
};
并查集的思想在于,最初初始化一个n的父节点为parent[n]并使其指向自身,然后通过外界条件不断吸纳与自身相连的元素成为一棵树,并使用parent[n]记录之间关系。
并查集查找自身的根节点比较方便。

京公网安备 11010502036488号