Python算法教程:强连通分量

强连通分量(strongly connected components, SCCs)是一个能让有向路径上所有节点彼此到达的最大子图。

Kosaraju的查找强连通分量算法

def strongly_connected_components(graph):
    transpose_graph = get_transpose_graph(graph)
    scc, seen = [], set()
    for u in dfs_top_sort(graph):
        if u in seen:
            continue
        component = walk(transpose_graph, u, seen)
        seen.update(component)
        scc.append(component)
    return scc


def get_transpose_graph(graph):
    transposed = {}
    for u in graph:
        transposed[u] = set()
    for u in graph:
        for v in graph[u]:
            transposed[v].add(u)
    return transposed


def dfs_top_sort(graph):
    visited, res = set(), []

    def recurse(u):
        if u in visited:
            return
        visited.add(u)
        for v in graph[u]:
            recurse(v)
        res.append(u)

    for u in graph:
        recurse(u)

    res.reverse()
    return res


def walk(graph, start, s=None):
    nodes, current = set(), dict()
    current[start] = None
    nodes.add(start)
    while nodes:
        u = nodes.pop()
        for v in graph[u].difference(current, s):
            nodes.add(v)
            current[v] = u
    return current


graph = {
    'a': set('bc'),
    'b': set('dei'),
    'c': set('d'),
    'd': set('ah'),
    'e': set('f'),
    'f': set('g'),
    'g': set('eh'),
    'h': set('i'),
    'i': set('h'),
}
print(strongly_connected_components(graph))
# [{'a': None, 'd': 'a', 'b': 'd', 'c': 'd'}, {'e': None, 'g': 'e', 'f': 'g'}, {'h': None, 'i': 'h'}]

(最近更新:2019年05月31日)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现求强连通分量,可以使用深度优先搜索(DFS)算法。以下是一个用 Python 实现的示例代码: ```python from collections import defaultdict class Graph: def __init__(self, vertices): self.V = vertices self.graph = defaultdict(list) self.Time = 0 def addEdge(self, u, v): self.graph[u].append(v) def SCCUtil(self, u, low, disc, stackMember, st): disc[u] = self.Time low[u] = self.Time self.Time += 1 stackMember[u] = True st.append(u) for v in self.graph[u]: if disc[v] == -1: # 如果 v 还没被访问过,则递归访问它 self.SCCUtil(v, low, disc, stackMember, st) low[u] = min(low[u], low[v]) elif stackMember[v] == True: # 如果 v 在栈中,则更新 low[u] low[u] = min(low[u], disc[v]) w = -1 # 存储强连通分量的顶点 if low[u] == disc[u]: while w != u: w = st.pop() print(w, end=" ") stackMember[w] = False print() def SCC(self): disc = [-1] * (self.V) low = [-1] * (self.V) stackMember = [False] * (self.V) st = [] for i in range(self.V): if disc[i] == -1: self.SCCUtil(i, low, disc, stackMember, st) # 示例用法 g1 = Graph(5) g1.addEdge(1, 0) g1.addEdge(0, 2) g1.addEdge(2, 1) g1.addEdge(0, 3) g1.addEdge(3, 4) print("强连通分量为:") g1.SCC() ``` 这段代码首先定义了一个 `Graph` 类,其中 `addEdge` 方法用于添加边。`SCCUtil` 方法是实现强连通分量的核心函数。`SCC` 方法用于遍历图中所有的强连通分量并打印出来。 在示例中,我们创建了一个包含 5 个顶点的图,并添加了几条边。然后调用 `SCC` 方法来获取强连通分量。输出结果将显示强连通分量的顶点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值