kosaraju.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. @source: http://codehiker.wordpress.com/2012/04/06/kosarajus-scc/
  5. I made minor changs
  6. """
  7. import sys
  8. sys.setrecursionlimit(300000)
  9. source = 'SCC.txt'
  10. N = 875714
  11. # globals
  12. visited = {}
  13. finish = {}
  14. leader = {}
  15. def get_g(source):
  16. """ Read the Graph from a textfile """
  17. G = {}
  18. Grev = {}
  19. for i in range(1, N+1):
  20. G[i] = []
  21. Grev[i] = []
  22. fin = open(source)
  23. for line in fin:
  24. v1 = int(line.split()[0])
  25. v2 = int(line.split()[1])
  26. G[v1].append(v2)
  27. Grev[v2].append(v1)
  28. fin.close()
  29. return G, Grev
  30. def init():
  31. for i in range(1, N+1):
  32. visited[i] = 0
  33. finish[i] = 0
  34. leader[i] = 0
  35. def dfs(G, i):
  36. global t
  37. visited[i] = 1
  38. leader[i] = s
  39. for j in G[i]:
  40. if(visited[j] == 0):
  41. dfs(G, j)
  42. t = t + 1
  43. finish[i] = t
  44. def dfs_loop(G):
  45. global t
  46. global s
  47. t = 0 # number of nodes processed so far
  48. s = 0 # current source vertex
  49. i = N
  50. while(i > 0):
  51. if(visited[i] == 0):
  52. s = i
  53. dfs(G, i)
  54. i = i-1
  55. if __name__ == "__main__":
  56. init()
  57. g, grev = get_g()
  58. dfs_loop(grev) # THE FIRST LOOP ON REVERSE GRAPH
  59. # construct new graph
  60. newGraph = {}
  61. for i in range(1, N+1):
  62. temp = []
  63. for x in g[i]:
  64. temp.append(finish[x])
  65. newGraph[finish[i]] = temp
  66. init()
  67. dfs_loop(newGraph) # THE SECOND LOOP
  68. # statistics
  69. lst = sorted(leader.values())
  70. stat = []
  71. pre = 0
  72. for i in range(0, N-1):
  73. if lst[i] != lst[i+1]:
  74. stat.append(i + 1 - pre)
  75. pre = i+1
  76. stat.append(N-pre)
  77. L = sorted(stat)
  78. L.reverse()
  79. print(L[0:5])