func (g LabeledDirected) TopologicalKahn(tr Directed) (ordering, cycle []NI) {
	var L, S []NI
	rem := make([]int, len(g.LabeledAdjacencyList))
	for n, fr := range tr.AdjacencyList {
		if len(fr) == 0 {
			S = append(S, NI(n))
		} else {
			rem[n] = len(fr)
		}
	}
	for len(S) > 0 {
		last := len(S) - 1  
		n := S[last]
		S = S[:last]
		L = append(L, n)  
		for _, m := range g.LabeledAdjacencyList[n] {
			if rem[m.To] > 0 {
				rem[m.To]--          
				if rem[m.To] == 0 {  
					S = append(S, m.To)  
				}
			}
		}
	}
	for c, in := range rem {
		if in > 0 {
			for _, nb := range g.LabeledAdjacencyList[c] {
				if rem[nb.To] > 0 {
					cycle = append(cycle, NI(c))
					break
				}
			}
		}
	}
	if len(cycle) > 0 {
		return nil, cycle
	}
	return L, nil
}
TopologicalKahn computes a topological ordering of a directed acyclic graph.

For an acyclic graph, return value ordering is a permutation of node numbers
in topologically sorted order and cycle will be nil.  If the graph is found
to be cyclic, ordering will be nil and cycle will be the path of a found
cycle.

This function is based on the algorithm by Arthur Kahn and requires the
transpose of g be passed as the argument.

There are equivalent labeled and unlabeled versions of this method.
package graph
func (g LabeledDirected) Balanced() bool {
	for n, in := range g.InDegree() {
		if in != len(g.LabeledAdjacencyList[n]) {
			return false
		}
	}
	return true
}
func (g LabeledDirected) Copy() (c LabeledDirected, ma int) {
	l, s := g.LabeledAdjacencyList.Copy()
	return LabeledDirected{l}, s
}
func (g LabeledDirected) Cyclic() (cyclic bool, fr NI, to Half) {
	a := g.LabeledAdjacencyList
	fr, to.To = -1, -1
	var temp, perm Bits
	var df func(NI)
	df = func(n NI) {
		switch {
		case temp.Bit(n) == 1:
			cyclic = true
			return
		case perm.Bit(n) == 1:
			return
		}
		temp.SetBit(n, 1)
		for _, nb := range a[n] {
			df(nb.To)
			if cyclic {
				if fr < 0 {
					fr, to = n, nb
				}
				return
			}
		}
		temp.SetBit(n, 0)
		perm.SetBit(n, 1)
	}
	for n := range a {
		if perm.Bit(NI(n)) == 1 {
			continue
		}
		if df(NI(n)); cyclic {  
			break
		}
	}
	return
}
func (g LabeledDirected) FromList() (*FromList, NI) {
	paths := make([]PathEnd, len(g.LabeledAdjacencyList))
	for i := range paths {
		paths[i].From = -1
	}
	for fr, to := range g.LabeledAdjacencyList {
		for _, to := range to {
			if paths[to.To].From >= 0 {
				return nil, to.To
			}
			paths[to.To].From = NI(fr)
		}
	}
	return &FromList{Paths: paths}, -1
}
func (g LabeledDirected) InDegree() []int {
	ind := make([]int, len(g.LabeledAdjacencyList))
	for _, nbs := range g.LabeledAdjacencyList {
		for _, nb := range nbs {
			ind[nb.To]++
		}
	}
	return ind
}
func (g LabeledDirected) IsTree(root NI) (isTree, allTree bool) {
	a := g.LabeledAdjacencyList
	var v Bits
	v.SetAll(len(a))
	var df func(NI) bool
	df = func(n NI) bool {
		if v.Bit(n) == 0 {
			return false
		}
		v.SetBit(n, 0)
		for _, to := range a[n] {
			if !df(to.To) {
				return false
			}
		}
		return true
	}
	isTree = df(root)
	return isTree, isTree && v.Zero()
}
func (g LabeledDirected) Tarjan(emit func([]NI) bool) {
	var indexed, stacked Bits
	a := g.LabeledAdjacencyList
	index := make([]int, len(a))
	lowlink := make([]int, len(a))
	x := 0
	var S []NI
	var sc func(NI) bool
	sc = func(n NI) bool {
		index[n] = x
		indexed.SetBit(n, 1)
		lowlink[n] = x
		x++
		S = append(S, n)
		stacked.SetBit(n, 1)
		for _, nb := range a[n] {
			if indexed.Bit(nb.To) == 0 {
				if !sc(nb.To) {
					return false
				}
				if lowlink[nb.To] < lowlink[n] {
					lowlink[n] = lowlink[nb.To]
				}
			} else if stacked.Bit(nb.To) == 1 {
				if index[nb.To] < lowlink[n] {
					lowlink[n] = index[nb.To]
				}
			}
		}
		if lowlink[n] == index[n] {
			var c []NI
			for {
				last := len(S) - 1
				w := S[last]
				S = S[:last]
				stacked.SetBit(w, 0)
				c = append(c, w)
				if w == n {
					if !emit(c) {
						return false
					}
					break
				}
			}
		}
		return true
	}
	for n := range a {
		if indexed.Bit(NI(n)) == 0 && !sc(NI(n)) {
			return
		}
	}
}
func (g LabeledDirected) TarjanForward() [][]NI {
	var r [][]NI
	g.Tarjan(func(c []NI) bool {
		r = append(r, c)
		return true
	})
	scc := make([][]NI, len(r))
	last := len(r) - 1
	for i, ci := range r {
		scc[last-i] = ci
	}
	return scc
}
func (g LabeledDirected) TarjanCondensation() (scc [][]NI, cd AdjacencyList) {
	scc = g.TarjanForward()
	cd = make(AdjacencyList, len(scc))               
	cond := make([]NI, len(g.LabeledAdjacencyList))  
	for cn := NI(len(scc) - 1); cn >= 0; cn-- {
		c := scc[cn]
		for _, n := range c {
			cond[n] = NI(cn)  
		}
		var tos []NI  
		var m Bits    
		m.SetBit(cn, 1)
		for _, n := range c {
			for _, to := range g.LabeledAdjacencyList[n] {
				if ct := cond[to.To]; m.Bit(ct) == 0 {
					m.SetBit(ct, 1)
					tos = append(tos, ct)
				}
			}
		}
		cd[cn] = tos
	}
	return
}
func (g LabeledDirected) Topological() (ordering, cycle []NI) {
	a := g.LabeledAdjacencyList
	ordering = make([]NI, len(a))
	i := len(ordering)
	var temp, perm Bits
	var cycleFound bool
	var cycleStart NI
	var df func(NI)
	df = func(n NI) {
		switch {
		case temp.Bit(n) == 1:
			cycleFound = true
			cycleStart = n
			return
		case perm.Bit(n) == 1:
			return
		}
		temp.SetBit(n, 1)
		for _, nb := range a[n] {
			df(nb.To)
			if cycleFound {
				if cycleStart >= 0 {
					x := len(ordering) - 1 - len(cycle)
					ordering[x] = n
					cycle = ordering[x:]
					if n == cycleStart {
						cycleStart = -1
					}
				}
				return
			}
		}
		temp.SetBit(n, 0)
		perm.SetBit(n, 1)
		i--
		ordering[i] = n
	}
	for n := range a {
		if perm.Bit(NI(n)) == 1 {
			continue
		}
		df(NI(n))
		if cycleFound {
			return nil, cycle
		}
	}
	return ordering, nil
}