Esempio n. 1
0
File: Lab05.cs Progetto: L-Dogg/ASD2
        /// <summary>
        /// Wyznacza silnie spójne składowe
        /// </summary>
        /// <param name="g">Badany graf</param>
        /// <param name="scc">Silnie spójne składowe (parametr wyjściowy)</param>
        /// <returns>Liczba silnie spójnych składowych</returns>
        /// <remarks>
        /// scc[v] = numer silnie spójnej składowej do której należy wierzchołek v<br/>
        /// (numerujemy od 0)<br/>
        /// <br/>
        /// Metoda uruchomiona dla grafu nieskierowanego zgłasza wyjątek <see cref="System.ArgumentException"/>.
        /// <br/>
        /// Graf wejściowy pozostaje niezmieniony.
        /// </remarks>
        public static int StronglyConnectedComponents(this Graph g, out int[] scc)
        {
            scc = new int[g.VerticesCount];
            int[] myscc = new int[g.VerticesCount];
            if (g.Directed == false)
            {
                throw new System.ArgumentException("Graph should be directed");
            }
            Graph           tmp     = Reverse(g);
            Stack <int>     S       = new Stack <int>(g.VerticesCount);
            Predicate <int> postFix = delegate(int n)
            {
                S.Push(n);
                return(true);
            };

            bool[] added = new bool[g.VerticesCount];
            int    cc    = 0;

            g.DFSearchAll(null, postFix, out cc, null);
            cc = 0;
            Predicate <int> AddToComponent = delegate(int n)
            {
                if (added[n])
                {
                    return(true);
                }
                myscc[n] = cc;
                added[n] = true;
                return(true);
            };

            while (S.Count > 0)
            {
                int v = S.Pop();
                if (added[v])
                {
                    continue;
                }
                tmp.DFSearchFrom(v, null, AddToComponent, null);
                cc++;
            }
            scc = myscc;
            return(cc);
        }