1、DFS
每调用一次DFS(u),就能遍历u所在的连通分量
class Solution {
private:
static const int N = 2010;
int n, G[N][N];
bool visited[N] = {false};
public:
int countComponents(int n, vector<vector<int>>& edges) {
this->n = n;
memset(G, 0, sizeof G);
for (vector<int> edge : edges){
int u = edge[0], v = edge[1];
G[u][v] = G[v][u] = 1;
}
int res = 0;
for (int i = 0; i < n; i++){
if (!visited[i]){
DFS(i);
res++;
}
}
return res;
}
void DFS(int u){
visited[u] = true;
for (int v = 0; v < n; v++){
if (G[u][v] != 0 && !visited[v])
DFS(v);
}
}
};
2、并查集
将两个节点看做集合,如果a、b之间有边,那么把a、b合并,最后计算集合中根节点的个数即可
class Solution {
private:
static const int N = 2010;
int father[N];
public:
int countComponents(int n, vector<vector<int>>& edges) {
int res = 0;
memset(father, 0, sizeof father);
for (int i = 0; i < n; i++) father[i] = i;
for (vector<int> edge : edges){
int a = edge[0], b = edge[1];
int FaA = findFather(a), FaB = findFather(b);
if (FaA != FaB){
father[FaB] = FaA; //将b的父节点连接到a所在的子树上
}
}
for (int i = 0; i < n; i++){
if (father[i] == i) res++;
}
return res;
}
int findFather(int a){
if (a != father[a]) father[a] = findFather(father[a]);
return father[a];
}
};