UNB/ CS/ David Bremner/ teaching/ cs3383/ lectures/ 30.0-demos/ topsort.py
#!/usr/bin/env python3
from collections import deque
def topsort(G):
    n = len(G)

    # Count inbound edges
    count = [0] * n
    for v in range(n):
        for (u,_) in G[v]:
            count[u] += 1

    # Find the sources
    Q = deque()
    for j in range(n):
        if count[j] == 0:
            Q.append(j)

    output = []
    rank = [0] * n
    while len(Q) > 0:
        v = Q.popleft()
        rank[v]=len(output)
        output.append(v)
        for (u,_) in G[v]:
            count[u] -= 1
            if count[u] == 0:
                Q.append(u)
    return (rank,output)

def draw_graph(O,G):
    print('digraph G { rankdir=TB')
    n = len(O)
    print('{edge    [style="invis"];')

    for j in range(n):
        if (j>0):
            print("r{:d} -> r{:d};".format(j-1,j));
        print('subgraph {{ rank="same" r{:d} [label="rank {:d}",shape="none"] {:d} }}'.format(j,j,O[j]))
    print('}')
    for v in range(n):
        for (u,_) in G[v]:
            print("{:d} -> {:d};".format(v,u))
    print("}")

if __name__ == "__main__":

    # [(dest,weight),...]    # from
    Graph = [ [(2,4),(3,4),(5,3)],
              [(0,4),(2,1),(3,3)],
              [(3,2),(4,4)],
              [(4,6)],
              [],
              [(4,5)] ]

    (rank,order) = topsort(Graph)
    draw_graph(order,Graph)