python表示有向图

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))
posted @ 2016-07-11 23:19  Salaku  阅读(5449)  评论(0编辑  收藏  举报