如何使用 BFS或DFS 算法设计算法以确定非连接图的连接组件,算法必须能够表示每个连通组件的顶点集。
这是我的理由:
1)将所有顶点初始化为未访问。
2)从任意顶点v开始执行图的DFS遍历。 如果DFS遍历不访问所有顶点,则返回false。
3)反转所有弧线(或找到图形的转置或反转)
4)在反转图中将所有顶点标记为未访问。
5)从相同的顶点v开始执行反向图的DFS遍历 (与步骤2相同)。如果DFS遍历不访问所有顶点,那么 返回false。否则返回true。
这个想法是,如果每个节点都可以从顶点v到达每个节点 节点可以达到v,然后图形强烈连接。在第2步中,我们 检查是否可以从v访问所有顶点。在步骤4中,我们检查是否全部 顶点可以到达v(在反向图中,如果所有顶点都可到达 从v开始,所有顶点都可以在原始图中达到v。)
如何改进此解决方案?
答案 0 :(得分:3)
怎么样
vertices
=输入results
=空列表vertices
中有顶点:
S
S
。vertices
中删除并添加到S
。S
添加到results
results
完成后,您将拥有一组顶点集,其中每个集都是从某个顶点搜索图形(使每个集中的顶点连接)。假设一个无向图,这应该可以正常工作(从头顶开始)。
答案 1 :(得分:1)
使用时间复杂度为O(V + E)的BFS或DFS可以轻松完成。
// this is the DFS solution
numCC = 0;
dfs_num.assign(V, UNVISITED); // sets all vertices’ state to UNVISITED
for (int i = 0; i < V; i++) // for each vertex i in [0..V-1]
if (dfs_num[i] == UNVISITED) // if vertex i is not visited yet
printf("CC %d:", ++numCC), dfs(i), printf("\n");
3个连接组件的上述代码输出类似于:
// CC 1: 0 1 2 3 4
// CC 2: 5
// CC 3: 6 7 8
答案 2 :(得分:0)
解决此问题的标准方法是从每个节点开始运行DFS。
首先将所有节点标记为未访问。然后,以任何顺序迭代节点。对于每个节点,如果它尚未标记为在连接的组件中,则从该节点运行DFS并将所有可到达节点标记为在同一CC中。如果节点已标记,请跳过它。然后,它一次发现一个CC的所有CC。
此外,这非常有效。如果有m个边和n个节点,则运行时第一步为O(n)(将所有节点标记为未访问),第二步为O(m + n),因为每个节点和边最多访问两次。因此整个运行时间为O(m + n)。
希望这有帮助!
答案 3 :(得分:0)
由于您似乎使用有向图,并且想要查找连接的组件(没有强连接),因此您必须先将图形转换为无向图。因此,对于每个顶点,在相反方向添加临时顶点。然后,您可以使用从尚未访问过的每个顶点开始的简单DFS来查找连接的组件。最后,您可以删除临时顶点。