| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- def strongly_connected_components(graph):
- index_counter = 0
- stack = []
- lowlinks = {}
- index = {}
- result = []
-
- def strongconnect(node, index_counter):
- index[node] = index_counter
- lowlinks[node] = index_counter
- index_counter += 1
- stack.append(node)
-
- try:
- successors = graph[node]
- except:
- successors = []
- # Depth first search
- for successor in successors:
- # Does the current node point to a node that was already
- # visited?
- if successor not in lowlinks:
- # Successor has not yet been visited; recurse on it
- strongconnect(successor, index_counter)
- lowlinks[node] = min(lowlinks[node],lowlinks[successor])
- elif successor in stack:
- # the successor is in the stack and hence in the
- # current strongly connected component (SCC)
- lowlinks[node] = min(lowlinks[node],index[successor])
-
- # If `node` is a root node, pop the stack and generate an SCC
- if lowlinks[node] == index[node]:
- connected_component = []
-
- while True:
- successor = stack.pop()
- connected_component.append(successor)
- if successor == node: break
- component = tuple(connected_component)
- # storing the result
- result.append(component)
-
- for node in graph:
- if node not in lowlinks:
- strongconnect(node, index_counter)
-
- return result
|