func (graph *Decycle) addFlippedEdge(src, dst *Node) {
	graph.info[src.ID].Out--
	graph.info[src.ID].In++
	graph.info[dst.ID].In--
	graph.info[dst.ID].Out++
	graph.addEdge(dst, src)
}
addFlippedEdge adds edge and flips it
package hier
func DefaultDecycle(graph *Graph) *Graph {
	decycle := NewDecycle(graph)
	decycle.Recurse = true
	decycle.Reorder = true
	decycle.Run()
	return graph
}
type Decycle struct {
	*Graph
	Recurse bool
	Reorder bool
	SkipUpdate bool
	info  []DecycleNodeInfo
	edges [][2]ID
}
func NewDecycle(graph *Graph) *Decycle {
	dg := &Decycle{}
	dg.Graph = graph
	dg.Recurse = false
	dg.Reorder = true
	return dg
}
type DecycleNodeInfo struct {
	Processed bool
	In, Out   int
}
func (graph *Decycle) Run() {
	if !graph.IsCyclic() {
		return
	}
	graph.info = make([]DecycleNodeInfo, graph.NodeCount())
	for _, node := range graph.Nodes {
		graph.info[node.ID].In = node.InDegree()
		graph.info[node.ID].Out = node.OutDegree()
	}
	graph.processNodes(*graph.Nodes.Clone())
	if !graph.SkipUpdate {
		graph.updateEdges()
	}
}
func (graph *Decycle) processNodes(nodes Nodes) {
	if !graph.Reorder {
		for _, node := range nodes {
			graph.process(node)
		}
	} else {
		var node *Node
		for len(nodes) > 0 {
			graph.sortAscending(nodes)
			node, nodes = nodes[len(nodes)-1], nodes[:len(nodes)-1]
			graph.process(node)
		}
	}
}
func (graph *Decycle) process(dst *Node) {
	if graph.info[dst.ID].Processed {
		return
	}
	graph.info[dst.ID].Processed = true
	var recurse Nodes
	for _, src := range dst.In {
		if src == dst {
			continue
		}
		if graph.info[src.ID].Processed {
			graph.addEdge(src, dst)
		} else {
			graph.addFlippedEdge(src, dst)
			if graph.Recurse {
				recurse.Append(src)
			}
		}
	}
	if graph.Recurse {
		graph.processNodes(recurse)
	}
}
func (graph *Decycle) addEdge(src, dst *Node) {
	graph.edges = append(graph.edges, [2]ID{src.ID, dst.ID})
}