tarjans-short.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. def strongly_connected_components(graph):
  2. index_counter = 0
  3. stack = []
  4. lowlinks = {}
  5. index = {}
  6. result = []
  7. def strongconnect(node, index_counter):
  8. index[node] = index_counter
  9. lowlinks[node] = index_counter
  10. index_counter += 1
  11. stack.append(node)
  12. try:
  13. successors = graph[node]
  14. except:
  15. successors = []
  16. # Depth first search
  17. for successor in successors:
  18. # Does the current node point to a node that was already
  19. # visited?
  20. if successor not in lowlinks:
  21. # Successor has not yet been visited; recurse on it
  22. strongconnect(successor, index_counter)
  23. lowlinks[node] = min(lowlinks[node],lowlinks[successor])
  24. elif successor in stack:
  25. # the successor is in the stack and hence in the
  26. # current strongly connected component (SCC)
  27. lowlinks[node] = min(lowlinks[node],index[successor])
  28. # If `node` is a root node, pop the stack and generate an SCC
  29. if lowlinks[node] == index[node]:
  30. connected_component = []
  31. while True:
  32. successor = stack.pop()
  33. connected_component.append(successor)
  34. if successor == node: break
  35. component = tuple(connected_component)
  36. # storing the result
  37. result.append(component)
  38. for node in graph:
  39. if node not in lowlinks:
  40. strongconnect(node, index_counter)
  41. return result