dfs_test = """
{
0:[5,1],
2:[0,3],
3:[5,2],
4:[3,2],
5:[4],
6:[9,4,0],
7:[6,8],
8:[7,9],
9:[11,10],
10:[12],
11:[4,12],
12:[9]
}
"""
topo_test = """
{
0:[1,5,6],
2:[0,3],
3:[5],
5:[4],
6:[4,9],
7:[6],
8:[7],
9:[10,11,12],
11:[12]
}
"""
scc_test ="""
{
0:[1,5],
2:[0,3],
3:[2,5],
4:[2,3],
5:[4],
6:[0,4,9],
7:[6,8],
8:[7,9],
9:[10,11],
10:[12],
11:[4,12],
12:[9]
}
"""
## 排序
def dfs_order(g):
visited = set()
pre_order = []
post_order = []
where_from = dict()
def dfs(n):
visited.add(n)
pre_order.append(n)
for x in g.get(n,[]):
if x not in visited:
where_from[x] = n
dfs(x)
post_order.append(n)
for x in g:
if x not in visited:
dfs(x)
return pre_order,post_order,post_order[::-1]
## 是否存在环路
def has_cycle(g):
where_from = dict()
visited = set()
stack = dict()
cycle = []
def dfs(n):
visited.add(n)
stack[n] = True
for x in g.get(n,[]):
if x not in visited:
where_from[x] = n
dfs(x)
elif stack.get(x,False):
cycle_path = graph.get_path(where_from,x,n)
if cycle_path:
cycle.append(cycle_path+[x])
stack[n] = False
for x in g:
if x not in visited:
dfs(x)
return cycle
## 增加一条边
def add_edge_x_to_y(g,x,y):
if x in g:
(g[x]).append(y)
else:
g[x] = []
add_edge_x_to_y(g,x,y)
## 反向
def reverse(g):
reversed = dict()
visited = set()
def dfs(n):
visited.add(n)
for x in g.get(n,[]):
add_edge_x_to_y(reversed,x,n)
for x in g:
if x not in visited:
dfs(x)
return reversed
def scc(g):
rev_graph_post_order_rev = dfs_order(reverse(g))[-1]
count = 0
cc = dict()
visited = set()
def dfs(n):
visited.add(n)
cc[n] = count
for x in g.get(n,[]):
if x not in visited:
dfs(x)
for x in rev_graph_post_order_rev:
if x not in visited:
count += 1
dfs(x)
return cc
if __name__ == '__main__':
print('i am alive')
g = eval(scc_test)
print(scc(g))