/// <summary>
        /// http://alrightchiu.github.io/SecondRound/graph-li-yong-dfsxun-zhao-dagde-topological-sorttuo-pu-pai-xu.html
        /// </summary>
        public static void TopologicalSort(int start, Graph <int> graph)
        {
            int num_vertex = graph.VerticesCount;

            // 第一次DFS(), 目的是取得finish[]
            DFS_Algo dfs = new DFS_Algo();

            dfs.DFS(start, graph);
            // 顯示 第一次DFS()後的finish[]
            Console.WriteLine("First DFS() on G, finish time:");
            dfs.finish.Print("finish");

            // 矩陣 finishLargetoSmall[] 用來儲存 finish[] 由大至小的vertex順序
            int[] finishLargetoSmall = new int[num_vertex];
            for (int i = 0; i < num_vertex; i++)
            {
                finishLargetoSmall[i] = i;
            }
            // QuickSort()會更新 finishLargetoSmall[] 成 finish[] 由大至小的vertex順序
            Sort_QuickSort_Graph.QuickSort(dfs.finish, 0, num_vertex - 1, finishLargetoSmall);

            // 列印出 finish[] 由大至小的vertex順序
            Console.WriteLine("Topological Sort:");
            Console.WriteLine("finish time Large to Small:");
            finishLargetoSmall.Print();
        }
Ejemplo n.º 2
0
        public static void main()
        {
            DFS_Algo dfs      = new DFS_Algo();
            var      vertices = new[] { 0, 1, 2, 3, 4, 5, 6, 7 };
            var      edges    = new[] { Tuple.Create(0, 1), Tuple.Create(0, 2), Tuple.Create(1, 3), Tuple.Create(2, 1), Tuple.Create(2, 5), Tuple.Create(3, 4), Tuple.Create(3, 5), Tuple.Create(5, 1), Tuple.Create(6, 4), Tuple.Create(6, 7), Tuple.Create(7, 6) };
            var      graph    = new Graph <int>(vertices, edges, GraphOption.Diirected);

            dfs.DFS(0, graph);
            dfs.PrintInfo();

            //想了很久總算可能想出為什麼  跑的結果  和 文章不一樣
            //應該是因為  BFS的時候  例子是 無向圖 undirected graph
            // graph的Add Edge方法也是針對無向圖設計的
            //  所以要再增加能接受有向圖的機制

            //  已加  推測沒錯  加了就成功了
        }
        /// <summary>
        /// http://alrightchiu.github.io/SecondRound/graph-li-yong-dfsxun-zhao-strongly-connected-componentscc.html#ref
        /// </summary>
        public static void PrintSCCs(int start, Graph <int> graph)
        {
            int num_vertex = graph.VerticesCount;

            // 第一次DFS(), 目的是取得finish[]
            DFS_Algo dfs = new DFS_Algo();

            dfs.DFS(start, graph);
            // 顯示 第一次DFS()後的finish[]
            Console.WriteLine("First DFS() on G, finish time:");
            dfs.finish.Print("finish");

            // 矩陣 finishLargetoSmall[] 用來儲存 finish[] 由大至小的vertex順序
            int[] finishLargetoSmall = new int[num_vertex];
            for (int i = 0; i < num_vertex; i++)
            {
                finishLargetoSmall[i] = i;
            }
            // QuickSort()會更新 finishLargetoSmall[] 成 finish[] 由大至小的vertex順序
            Sort_QuickSort_Graph.QuickSort(dfs.finish, 0, num_vertex - 1, finishLargetoSmall);

            // 列印出 finish[] 由大至小的vertex順序
            Console.WriteLine("finish time Large to Small:");
            finishLargetoSmall.Print();


            // gT代表Transpose of Graph
            var gT = graph.GetTranspose();

            // 第二次DFS(), 執行在gT
            DFS_Algo dfsGT = new DFS_Algo();

            dfsGT.DFS_WithOrder(start, gT, finishLargetoSmall);

            // 顯示 第二次DFS()後的finish[]
            Console.WriteLine("Second DFS() on gT, finish time:\n");
            dfsGT.finish.Print("finish");
            // 顯示 第二次DFS()後的predecessor[]
            Console.WriteLine("predecessor[] before SetCollapsing:\n");
            dfsGT.predecessor.Print("predecessor");

            dfsGT.SetCollapsing();
            //這個有點沒品  他竟然沒有附  SetCollapsing  的程式碼
            //http://alrightchiu.github.io/SecondRound/graph-li-yong-dfshe-bfsxun-zhao-connected-component.html
            //原文是有圖說解釋得很詳細   簡單來說  把一個圖的所有點   改變成直接連結到Root
            //看來是出作業自己寫
            //不過找到這篇有類似的程式碼  http://alrightchiu.github.io/SecondRound/setyi-arraybiao-shi.html
            //來參考看看
            //實際想想看,這邊使用的機制 就是 Adj List   所以就要用AdjList的概念做法來做到
            //那就主要是  刪除邊  增加邊   還有把predecessor設定為root
            //predecessor隔天起來就忘記   他也就是上一層的父節點  就是DFS 一點走到下個點 一點就是下點的pred
            //所以就是一個點對一個pred  也就是dfs類中的那個array啦


            // 顯示 SetCollapsing後的predecessor[]
            Console.WriteLine("predecessor after SetCollapsing:\n");
            dfsGT.predecessor.Print("predecessor");

            // 如同在undirected graph中尋找connected component
            int num_cc = 0;

            for (int i = 0; i < num_vertex; i++)
            {
                if (dfsGT.GetPredecessor(i) < 0)
                {
                    Console.WriteLine($"SCC#{++num_cc}: {i} ");
                    for (int j = 0; j < num_vertex; j++)
                    {
                        if (dfsGT.GetPredecessor(j) == i)
                        {
                            Console.WriteLine(j + " ");
                        }
                    }
                }
            }
        }