private void TopoSort(Node cur)
        {
            if (_states.TryGetValue(cur, out var b))
            {
                if (!b)
                {
                    throw new InvalidOperationException("A cycle has been encountered");
                }
                return;
            }

            _states[cur] = false;
            for (var i = 0; i < cur.Outgoing.Count; i++)
            {
                TopoSort(cur.Outgoing[i]);
            }
            _states[cur] = true;
            SortedNodes.Add(cur);
        }
        public override void AddEdge(Node src, Node dest)
        {
            for (; SortedNodes.Count < Nodes.Count;)
            {
                SortedNodes.Add(Nodes[SortedNodes.Count]);
            }
            if (src.Index < dest.Index)
            {
                src.Outgoing.Add(dest);
                dest.Incoming.Add(src);
                return;
            }
            _deltaPlus.Clear();
            Dfs(dest, _deltaPlus, n => n.Outgoing, dest.Index, src.Index);
            _deltaMinus.Clear();
            Dfs(src, _deltaMinus, n => n.Incoming, dest.Index, src.Index);
            _deltaPlusList.Clear();
            _deltaPlusList.AddRange(_deltaPlus.OrderBy(node => node.Index));
            _deltaPlus.IntersectWith(_deltaMinus);
            if (_deltaPlus.Count > 0)
            {
                throw new InvalidOperationException("The edge to be added would introduce a cycle");
            }
            src.Outgoing.Add(dest);
            dest.Incoming.Add(src);
            _deltaMinusList.Clear();
            _deltaMinusList.AddRange(_deltaMinus.OrderBy(node => node.Index));
            _merged.Clear();
            int f = 0, s = 0;

            while (f < _deltaPlusList.Count && s < _deltaMinusList.Count)
            {
                if (_deltaPlusList[f].Index < _deltaMinusList[s].Index)
                {
                    _merged.Add(_deltaPlusList[f].Index);
                    f++;
                }
                else
                {
                    _merged.Add(_deltaMinusList[s].Index);
                    s++;
                }
            }
            for (; f < _deltaPlusList.Count; f++)
            {
                _merged.Add(_deltaPlusList[f].Index);
            }
            for (; s < _deltaMinusList.Count; s++)
            {
                _merged.Add(_deltaMinusList[s].Index);
            }
            var cEntry = 0;

            for (int q = 0; q < _merged.Count; q++)
            {
                var cNode = cEntry < _deltaMinusList.Count ? _deltaMinusList[cEntry] : _deltaPlusList[cEntry - _deltaMinusList.Count];
                cEntry++;
                SortedNodes[_merged[q]] = cNode;
            }

            for (int q = 0; q < _merged.Count; q++)
            {
                SortedNodes[_merged[q]].Index = _merged[q];
            }
        }