12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- 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
|