📚 The CoCalc Library - books, templates and other resources
cocalc-examples / martinthoma-latex-examples / presentations / ICPC-Referat / Material / tarjans-algorithm.py
132939 viewsLicense: OTHER
def strongly_connected_components(graph):1"""2Tarjan's Algorithm (named for its discoverer, Robert Tarjan) is a3graph theory algorithm for finding the strongly connected4components of a graph.56Based on: http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm7@author: Dries Verdegem, some minor edits by Martin Thoma8@source: http://www.logarithmic.net/pfh/blog/012080831689"""1011index_counter = 012stack = []13lowlinks = {}14index = {}15result = []1617def strongconnect(node, index_counter):18print("Start with node: %s###########################" % node)19# set the depth index for this node to the smallest unused index20print("lowlinks:\t%s" % lowlinks)21print("index:\t%s" % index)22print("stack:\t%s" % stack)2324index[node] = index_counter25lowlinks[node] = index_counter26index_counter += 127stack.append(node)2829# Consider successors of `node`30try:31successors = graph[node]32except:33successors = []3435# Depth first search36for successor in successors:37# Does the current node point to a node that was already38# visited?39if successor not in lowlinks:40print("successor not in lowlinks: %s -> %s (node, successor)" %41(node, successor))42# Successor has not yet been visited; recurse on it43strongconnect(successor, index_counter)44lowlinks[node] = min(lowlinks[node], lowlinks[successor])45elif successor in stack:46# else:47print("successor in stack: %s -> %s" % (node, successor))48# the successor is in the stack and hence in the49# current strongly connected component (SCC)50lowlinks[node] = min(lowlinks[node], index[successor])51else:52print("This happens sometimes. node: %s, successor: %s" %53(node, successor))54print("Lowlinks: %s" % lowlinks)55print("stack: %s" % stack)5657# If `node` is a root node, pop the stack and generate an SCC58if lowlinks[node] == index[node]:59print("Got root node: %s (index/lowlink: %i)" %60(node, lowlinks[node]))61connected_component = []6263while True:64successor = stack.pop()65print("pop: %s" % successor)66connected_component.append(successor)67if successor == node:68break6970component = tuple(connected_component)7172# storing the result73result.append(component)74else:75print("Node: %s, lowlink: %i, index: %i" %76(node, lowlinks[node], index[node]))7778for node in graph:79if node not in lowlinks:80strongconnect(node, index_counter)8182return result8384graph = {'a': ['b'],85'b': ['c'],86'c': ['d', 'e'],87'd': ['a', 'e', 'h'],88'e': ['c', 'f'],89'f': ['g', 'i'],90'g': ['h', 'f'],91'h': ['j'],92'i': ['g', 'f'],93'j': ['i'],94'k': [],95'h': []}9697print strongly_connected_components(graph)9899100