public DataDirectedGraph CreateReverse()
        {
            int n = Graph.Vertexes.Length;

            DataDirectedGraph r = new DataDirectedGraph();
            r.CountVertexes = n;

            r.Graph = new GraphAdj();
            r.Graph.Vertexes = new List<int>[n];
            for(int i = 0; i < n; i++)
            {
                r.Graph.Vertexes[i] = new List<int>();
            }
                 
            for (int v = 0; v < n; v++)
            {
                if (Graph.Vertexes[v] == null)
                {
                    continue;
                }
                foreach (int w in Graph.Vertexes[v])
                {
                    r.Graph.Vertexes[w].Add(v);
                    r.CountEdges++;
                }
            }

            return r;
        }
        static void Main(string[] args)
        {
            DataDirectedGraph data = new DataDirectedGraph("Strongly Connected Components.txt");
            //data.Print();
            //Console.WriteLine("\r\nFinish!");
            //Console.ReadKey();

            int r = StronglyConnectedComponents(data);

            Console.WriteLine(r);
            Console.WriteLine("\r\nFinish!");
            Console.ReadKey();
        }
        static private void DfsOnReverse(DataDirectedGraph g, int v)
        {
            markedReverse[v] = true;
            foreach (int w in g.Graph.Vertexes[v])
            {
                if (markedReverse[w])
                {
                    continue;
                }
                DfsOnReverse(g, w);
            }

            postOrder.Enqueue(v);
        }
        static void Main(string[] args)
        {
            DataDirectedGraph graph = new DataDirectedGraph("Topological Sorting.txt");
            //graph.Print();
            //Console.WriteLine("Finish!");
            //Console.ReadKey();

            int[] r = TopologicalSorting(graph);

            Utils.PrintArrayToFile(r);
            Console.WriteLine();
            Console.WriteLine("Finish!");
            Console.ReadKey();
        }
        private static void DFS(DataDirectedGraph g, int v)
        {
            if (marked[v] != 0)
            {
                return;
            }

            marked[v] = 1;

            if (null != g.Graph.Vertexes[v])
            {
                foreach (int i in g.Graph.Vertexes[v])
                {
                    DFS(g, i);
                }
            }

            reversePost.Push(v);
        }
        static int StronglyConnectedComponents(DataDirectedGraph g)
        {
            int n = g.Graph.Vertexes.Length;

            DataDirectedGraph r = g.CreateReverse();

            postOrder = new Queue<int>();
            markedReverse = new bool[n];

            for (int v = 0; v < n; v++)
            {
                if (markedReverse[v])
                {
                    continue;
                }
                DfsOnReverse(r, v);
            }


            marked = new bool[n];
            id = new int[n];

            Stack<int> queueReversePost = new Stack<int>();
            foreach (int v in postOrder)
            {
                queueReversePost.Push(v);
            }

            foreach (int v in queueReversePost)
            {
                if (marked[v])
                {
                    continue;
                }
                Dfs(g, v);
                count++;
            }
            return count;
        }
        private static int[] TopologicalSorting(DataDirectedGraph g)
        {
            int n = g.Graph.Vertexes.Length;
            marked = new int[n];
            reversePost = new Stack<int>();

            for (int v = 0; v < n; v++)
            {
                DFS(g, v);
            }

            int[] r = new int[reversePost.Count];

            int i = 0;
            while (reversePost.Count != 0)
            {
                r[i] = reversePost.Pop() + 1;
                i++;
            }

            return r;
        }
 static private void Dfs(DataDirectedGraph g, int v)
 {
     marked[v] = true;
     id[v] = count;
     if (g.Graph.Vertexes[v] == null)
     {
         return;
     }
     foreach (int w in g.Graph.Vertexes[v])
     {
         if (marked[w])
         {
             continue;
         }
         Dfs(g, w);
     }
 }