tarjans-short.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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:
  35. break
  36. component = tuple(connected_component)
  37. # storing the result
  38. result.append(component)
  39. for node in graph:
  40. if node not in lowlinks:
  41. strongconnect(node, index_counter)
  42. return result