func (g johnsonGraph) indexOf(id int64) int {
	return g.index[id]
}
indexOf returns the index of the retained node for the given node ID.
package topo
import (
	"sort"
	"gonum.org/v1/gonum/graph"
	"gonum.org/v1/gonum/graph/internal/ordered"
	"gonum.org/v1/gonum/graph/internal/set"
	"gonum.org/v1/gonum/graph/iterator"
)
type johnson struct {
	adjacent johnsonGraph  
	b        []set.Ints    
	blocked  []bool
	s        int
	stack []graph.Node
	result [][]graph.Node
}
func DirectedCyclesIn(g graph.Directed) [][]graph.Node {
	jg := johnsonGraphFrom(g)
	j := johnson{
		adjacent: jg,
		b:        make([]set.Ints, len(jg.orig)),
		blocked:  make([]bool, len(jg.orig)),
	}
	for j.s < len(j.adjacent.orig)-1 {
		sccs := TarjanSCC(j.adjacent.subgraph(j.s))
		j.adjacent = j.adjacent.sccSubGraph(sccs, 2)  
		if j.adjacent.order() == 0 {
			break
		}
		if s := j.adjacent.leastVertexIndex(); s < j.s {
			j.s = s
		}
		for i, v := range j.adjacent.orig {
			if !j.adjacent.nodes.Has(v.ID()) {
				continue
			}
			if len(j.adjacent.succ[v.ID()]) > 0 {
				j.blocked[i] = false
				j.b[i] = make(set.Ints)
			}
		}
		_ = j.circuit(j.s)
		j.s++
	}
	return j.result
}
func (j *johnson) circuit(v int) bool {
	f := false
	n := j.adjacent.orig[v]
	j.stack = append(j.stack, n)
	j.blocked[v] = true
	for w := range j.adjacent.succ[n.ID()] {
		w := j.adjacent.indexOf(w)
		if w == j.s {
			r := make([]graph.Node, len(j.stack)+1)
			copy(r, j.stack)
			r[len(r)-1] = j.adjacent.orig[j.s]
			j.result = append(j.result, r)
			f = true
		} else if !j.blocked[w] {
			if j.circuit(w) {
				f = true
			}
		}
	}
	if f {
		j.unblock(v)
	} else {
		for w := range j.adjacent.succ[n.ID()] {
			j.b[j.adjacent.indexOf(w)].Add(v)
		}
	}
	j.stack = j.stack[:len(j.stack)-1]
	return f
}
func (j *johnson) unblock(u int) {
	j.blocked[u] = false
	for w := range j.b[u] {
		j.b[u].Remove(w)
		if j.blocked[w] {
			j.unblock(w)
		}
	}
}
type johnsonGraph struct {
	orig  []graph.Node
	index map[int64]int
	nodes set.Int64s
	succ  map[int64]set.Int64s
}
func johnsonGraphFrom(g graph.Directed) johnsonGraph {
	nodes := graph.NodesOf(g.Nodes())
	sort.Sort(ordered.ByID(nodes))
	c := johnsonGraph{
		orig:  nodes,
		index: make(map[int64]int, len(nodes)),
		nodes: make(set.Int64s, len(nodes)),
		succ:  make(map[int64]set.Int64s),
	}
	for i, u := range nodes {
		uid := u.ID()
		c.index[uid] = i
		for _, v := range graph.NodesOf(g.From(uid)) {
			if c.succ[uid] == nil {
				c.succ[uid] = make(set.Int64s)
				c.nodes.Add(uid)
			}
			c.nodes.Add(v.ID())
			c.succ[uid].Add(v.ID())
		}
	}
	return c
}
func (g johnsonGraph) order() int { return g.nodes.Count() }