#include <vector>
class Solution
{
// 访问标记数组:vis[i]为true表示第i个节点已被访问
// 大小210是预设的最大节点数,适用于节点数量不超过210的场景
bool vis[210] = {false};
public:
// 计算图中连通分量的数量
// 参数m:图的邻接矩阵表示,m[i][j]为非0值表示节点i和j相连
int citys(vector<vector<int> >& m)
{
int n = m.size(); // 获取节点数量(邻接矩阵的行数)
int ret = 0; // 记录连通分量的数量,初始为0
// 遍历所有节点
for(int i = 0; i < n; i++)
{
// 如果当前节点未被访问,说明发现了一个新的连通分量
if(!vis[i])
{
ret++; // 连通分量数量加1
dfs(m, i); // 从当前节点开始DFS,标记整个连通分量的节点为已访问
}
}
return ret; // 返回连通分量的总数
}
// 深度优先搜索(DFS):从pos节点出发,标记所有与其连通的节点
// 参数m:邻接矩阵;pos:当前搜索的节点索引
void dfs(vector<vector<int>>& m, int pos)
{
vis[pos] = true; // 标记当前节点为已访问
// 遍历所有节点,寻找与当前节点pos相连且未被访问的节点
for(int i = 0; i < m.size(); i++)
{
// 条件:节点i未被访问,且节点pos与节点i相连(m[pos][i]非0)
if(!vis[i] && m[pos][i])
{
dfs(m, i); // 递归访问节点i,继续深入搜索
}
}
}
};
这段代码的核心功能是计算一个无向图中连通分量的数量。连通分量指的是图中 "相互连通的节点组成的最大子集"(即子集中的任意两个节点都能通过路径连接,且子集外的节点无法与子集内节点连接)。
- 数据结构与变量vis[210]:布尔数组,用于标记节点是否被访问过,避免重复处理同一节点邻接矩阵m:通过二维数组表示图,m[i][j]的值非零时,表示节点i和节点j之间有边相连
- 主函数citys的逻辑遍历所有节点,对每个未访问的节点:计数器ret加 1(发现新的连通分量)调用dfs函数,递归标记该连通分量的所有节点为 "已访问"最终返回ret,即连通分量的总数
- 辅助函数dfs的逻辑标记当前节点pos为已访问遍历所有节点,找到与pos相连且未访问的节点,递归调用dfs继续搜索作用是 "扩散式" 标记整个连通分量,确保每个连通分量只被计数一次

京公网安备 11010502036488号