📜  在有向图中查找弱连通分量(1)

📅  最后修改于: 2023-12-03 15:37:43.595000             🧑  作者: Mango

在有向图中查找弱连通分量

弱连通分量是指在有向图中,两个点之间存在至少一条有向路径,无论是正向路径还是反向路径。求解弱连通分量可以通过深度优先搜索来实现。

算法原理
  1. 对于每个节点,遍历其可达的节点,标记已经访问节点;
  2. 变换有向图的方向(即改变所有边的方向),对所有未访问过的节点进行同样操作,此时得到的可达节点即为之前未可达的节点,标记已经访问节点;
  3. 将两次遍历得到的访问节点集合取并集,即得到弱连通分量。
实现代码
伪代码
1 procedure DFS(v)
2 visited[v] = true
3 for each child w of v in graph
4    if not visited[w] then DFS(w)
 
5 procedure FindStronglyConnectedComponents()
6 for each vertex v in graph
7    if not visited[v] 
8        then DFS(v)
9        add v to set A
 
10 reverse the direction of all arcs in the graph 
11 mark all vertices as not visited
12 for each vertex v in set A in reverse order
13    if not visited[v] 
14        then DFS(v)
15        add v to set B
 
16 return set(A), set(B)
Python实现代码
from collections import defaultdict
 
def dfs(v, visited, graph, stack):
    visited[v] = True
    for i in graph[v]:
        if not visited[i]:
            dfs(i, visited, graph, stack)
    stack = stack.append(v)
 
def get_transpose(graph):
    g = defaultdict(list)
    for i in graph:
        for j in graph[i]:
            g[j].append(i)
    return g
 
def get_strongly_connected_components(graph):
    n = len(graph)
    visited = [False] * n
    stack = []
 
    for i in range(n):
        if not visited[i]:
            dfs(i, visited, graph, stack)
    transposed_graph = get_transpose(graph)
    visited = [False] * n
    result = []
 
    while stack:
        i = stack.pop()
        if not visited[i]:
            temp = []
            dfs(i, visited, transposed_graph, temp)
            result.append(temp)
    return result
性能分析

时间复杂度为O(N + E)。如果使用Tarjan算法,则时间复杂度可以优化到O(N)。空间复杂度为O(N + E)。