Example #1
0
File: TST.cs Project: zzhi/Algs4Net
        private void collect(Node x, StringBuilder prefix, int i, string pattern, LinkedQueue <string> queue)
        {
            if (x == null)
            {
                return;
            }
            char c = pattern[i];

            if (c == '.' || c < x.c)
            {
                collect(x.left, prefix, i, pattern, queue);
            }
            if (c == '.' || c == x.c)
            {
                if (i == pattern.Length - 1 && x.val != null)
                {
                    queue.Enqueue(prefix.ToString() + x.c);
                }
                if (i < pattern.Length - 1)
                {
                    collect(x.mid, prefix.Append(x.c), i + 1, pattern, queue);
                    prefix.Remove(prefix.Length - 1, 1);
                }
            }
            if (c == '.' || c > x.c)
            {
                collect(x.right, prefix, i, pattern, queue);
            }
        }
Example #2
0
        /// <summary>
        /// Returns all of the keys in the symbol table that match <c>pattern</c>,
        /// where . symbol is treated as a wildcard character.</summary>
        /// <param name="pattern">the pattern</param>
        /// <returns>all of the keys in the symbol table that match <c>pattern</c>
        /// as an iterable, where . is treated as a wildcard character.</returns>
        ///
        public IEnumerable <string> KeysThatMatch(string pattern)
        {
            LinkedQueue <string> results = new LinkedQueue <string>();

            collect(root, new StringBuilder(), pattern, results);
            return(results);
        }
Example #3
0
        private void collect(Node x, StringBuilder prefix, string pattern, LinkedQueue <string> results)
        {
            if (x == null)
            {
                return;
            }
            int d = prefix.Length;

            if (d == pattern.Length && x.Value != null)
            {
                results.Enqueue(prefix.ToString());
            }
            if (d == pattern.Length)
            {
                return;
            }
            char c = pattern[d];

            if (c == '.')
            {
                for (int i = 0; i < R; i++)
                {
                    prefix.Append(alphabet.ToChar(i));
                    collect(x[i], prefix, pattern, results);
                    prefix.Remove(prefix.Length - 1, 1);
                }
            }
            else
            {
                prefix.Append(c);
                collect(x[alphabet.ToIndex(c)], prefix, pattern, results);
                prefix.Remove(prefix.Length - 1, 1);
            }
        }
Example #4
0
File: TST.cs Project: zzhi/Algs4Net
        /// <summary>
        /// Returns all of the keys in the symbol table that match <c>pattern</c>,
        /// where . symbol is treated as a wildcard character.</summary>
        /// <param name="pattern">the pattern</param>
        /// <returns>all of the keys in the symbol table that match <c>pattern</c>
        /// as an iterable, where . is treated as a wildcard character.</returns>
        ///
        public IEnumerable <string> KeysThatMatch(string pattern)
        {
            LinkedQueue <string> queue = new LinkedQueue <string>();

            collect(root, new StringBuilder(), 0, pattern, queue);
            return(queue);
        }
Example #5
0
        // breadth-first search from multiple sources
        private void bfs(Graph G, IEnumerable <int> sources)
        {
            LinkedQueue <int> q = new LinkedQueue <int>();

            foreach (int s in sources)
            {
                marked[s] = true;
                distTo[s] = 0;
                q.Enqueue(s);
            }
            while (!q.IsEmpty)
            {
                int v = q.Dequeue();
                foreach (int w in G.Adj(v))
                {
                    if (!marked[w])
                    {
                        edgeTo[w] = v;
                        distTo[w] = distTo[v] + 1;
                        marked[w] = true;
                        q.Enqueue(w);
                    }
                }
            }
        }
Example #6
0
        // is there an augmenting path?
        // if so, upon termination edgeTo[] will contain a parent-link representation of such a path
        // this implementation finds a shortest augmenting path (fewest number of edges),
        // which performs well both in theory and in practice
        private bool hasAugmentingPath(FlowNetwork G, int s, int t)
        {
            edgeTo = new FlowEdge[G.V];
            marked = new bool[G.V];

            // breadth-first search
            LinkedQueue <int> queue = new LinkedQueue <int>();

            queue.Enqueue(s);
            marked[s] = true;
            while (!queue.IsEmpty && !marked[t])
            {
                int v = queue.Dequeue();

                foreach (FlowEdge e in G.Adj(v))
                {
                    int w = e.Other(v);

                    // if residual capacity from v to w
                    if (e.ResidualCapacityTo(w) > 0)
                    {
                        if (!marked[w])
                        {
                            edgeTo[w] = e;
                            marked[w] = true;
                            queue.Enqueue(w);
                        }
                    }
                }
            }
            // is there an augmenting path?
            return(marked[t]);
        }
Example #7
0
        // breadth-first search from a single source
        private void bfs(Graph G, int s)
        {
            LinkedQueue <int> q = new LinkedQueue <int>();

            for (int v = 0; v < G.V; v++)
            {
                distTo[v] = INFINITY;
            }
            distTo[s] = 0;
            marked[s] = true;
            q.Enqueue(s);

            while (!q.IsEmpty)
            {
                int v = q.Dequeue();
                foreach (int w in G.Adj(v))
                {
                    if (!marked[w])
                    {
                        edgeTo[w] = v;
                        distTo[w] = distTo[v] + 1;
                        marked[w] = true;
                        q.Enqueue(w);
                    }
                }
            }
        }
Example #8
0
        /// <summary>
        /// Returns all keys in this symbol table in the given range,
        /// as an <c>IEnumerable</c>.</summary>
        /// <returns>all keys in this symbol table between <c>lo</c>
        ///        (inclusive) and <c>hi</c> (exclusive)</returns>
        /// <param name="lo">lower bound key</param>
        /// <param name="hi">upper bound key</param>
        /// <exception cref="ArgumentNullException">if either <c>lo</c> or <c>hi</c>
        ///        is <c>null</c></exception>
        ///
        public IEnumerable <Key> Keys(Key lo, Key hi)
        {
            if (lo == null)
            {
                throw new ArgumentNullException("first argument to Count is null");
            }
            if (hi == null)
            {
                throw new ArgumentNullException("second argument to Count is null");
            }

            LinkedQueue <Key> queue = new LinkedQueue <Key>();

            if (lo == null)
            {
                throw new ArgumentNullException("lo is null in keys()");
            }
            if (hi == null)
            {
                throw new ArgumentNullException("hi is null in keys()");
            }
            if (lo.CompareTo(hi) > 0)
            {
                return(queue);
            }
            for (int i = Rank(lo); i < Rank(hi); i++)
            {
                queue.Enqueue(keys[i]);
            }
            if (Contains(hi))
            {
                queue.Enqueue(keys[Rank(hi)]);
            }
            return(queue);
        }
Example #9
0
File: CC.cs Project: zzhi/Algs4Net
        public static void MainTest(string[] args)
        {
            TextInput input = new TextInput(args[0]);
            Graph     G     = new Graph(input);

            CC cc = new CC(G);

            // number of connected components
            int M = cc.Count;

            Console.WriteLine(M + " components");

            // compute list of vertices in each connected component
            LinkedQueue <int>[] components = new LinkedQueue <int> [M];
            for (int i = 0; i < M; i++)
            {
                components[i] = new LinkedQueue <int>();
            }
            for (int v = 0; v < G.V; v++)
            {
                components[cc.Id(v)].Enqueue(v);
            }

            // print results
            for (int i = 0; i < M; i++)
            {
                foreach (int v in components[i])
                {
                    Console.Write(v + " ");
                }
                Console.WriteLine();
            }
        }
Example #10
0
        /// <summary>
        /// Returns all of the keys in the set that start with <c>prefix</c>.</summary>
        /// <param name="prefix">the prefix</param>
        /// <returns>all of the keys in the set that start with <c>prefix</c>
        /// as an iterable</returns>
        ///
        public IEnumerable <string> KeysWithPrefix(string prefix)
        {
            LinkedQueue <string> results = new LinkedQueue <string>();
            Node x = get(root, prefix, 0);

            collect(x, new StringBuilder(prefix), results);
            return(results);
        }
Example #11
0
        // is there an augmenting path?
        // an alternating path is a path whose edges belong alternately to the matching and not to the matchign
        // an augmenting path is an alternating path that starts and ends at unmatched vertices
        //
        // if so, upon termination adj[] contains the level graph;
        // if not, upon termination marked[] specifies those vertices reachable via an alternating path
        // from one side of the bipartition
        private bool hasAugmentingPath(Graph G)
        {
            // shortest path distances
            marked = new bool[V];
            distTo = new int[V];
            for (int v = 0; v < V; v++)
            {
                distTo[v] = int.MaxValue;
            }

            // breadth-first search (starting from all unmatched vertices on one side of bipartition)
            LinkedQueue <int> queue = new LinkedQueue <int>();

            for (int v = 0; v < V; v++)
            {
                if (bipartition.Color(v) && !IsMatched(v))
                {
                    queue.Enqueue(v);
                    marked[v] = true;
                    distTo[v] = 0;
                }
            }

            // run BFS until an augmenting path is found
            // (and keep going until all vertices at that distance are explored)
            bool hasAugmentingPath = false;

            while (!queue.IsEmpty)
            {
                int v = queue.Dequeue();
                foreach (int w in G.Adj(v))
                {
                    // forward edge not in matching or backwards edge in matching
                    if (isResidualGraphEdge(v, w))
                    {
                        if (!marked[w])
                        {
                            distTo[w] = distTo[v] + 1;
                            marked[w] = true;
                            if (!IsMatched(w))
                            {
                                hasAugmentingPath = true;
                            }

                            // stop enqueuing vertices once an alternating path has been discovered
                            // (no vertex on same side will be marked if its shortest path distance longer)
                            if (!hasAugmentingPath)
                            {
                                queue.Enqueue(w);
                            }
                        }
                    }
                }
            }

            return(hasAugmentingPath);
        }
Example #12
0
        /// <summary>
        /// Returns all keys in the symbol table as an <c>Iterable</c>.
        /// To iterate over all of the keys in the symbol table named <c>st</c>,
        /// use the foreach notation: <c>foreach (Key key in st.Keys())</c>.</summary>
        /// <returns>all keys in the sybol table</returns>
        ///
        public IEnumerable <Key> Keys()
        {
            LinkedQueue <Key> queue = new LinkedQueue <Key>();

            for (Node x = first; x != null; x = x.next)
            {
                queue.Enqueue(x.key);
            }
            return(queue);
        }
Example #13
0
        public static void MainTest(string[] args)
        {
            TextInput StdIn = new TextInput();

            string filename = args[0];

            char[]    separator = args[1].ToCharArray();
            TextInput input     = new TextInput(filename);

            ST <string, LinkedQueue <string> > st = new ST <string, LinkedQueue <string> >();
            ST <string, LinkedQueue <string> > ts = new ST <string, LinkedQueue <string> >();

            while (input.HasNextLine())
            {
                string   line   = input.ReadLine();
                string[] fields = line.Split(separator);
                string   key    = fields[0];
                for (int i = 1; i < fields.Length; i++)
                {
                    string val = fields[i];
                    if (!st.Contains(key))
                    {
                        st[key] = new LinkedQueue <string>();
                    }
                    if (!ts.Contains(val))
                    {
                        ts[val] = new LinkedQueue <string>();
                    }
                    st[key].Enqueue(val);
                    ts[val].Enqueue(key);
                }
            }

            Console.WriteLine("Done indexing");

            // read queries from standard input, one per line
            while (!StdIn.IsEmpty)
            {
                string query = StdIn.ReadLine();
                if (st.Contains(query))
                {
                    foreach (string vals in st[query])
                    {
                        Console.WriteLine("  " + vals);
                    }
                }
                if (ts.Contains(query))
                {
                    foreach (string keys in ts[query])
                    {
                        Console.WriteLine("  " + keys);
                    }
                }
            }
        }
Example #14
0
        /// <summary>
        /// Returns all keys in this symbol table as an <c>Iterable</c>.
        /// To iterate over all of the keys in the symbol table named <c>st</c>,
        /// use the foreach notation: <c>foreach (Key key in st.Keys())</c>.</summary>
        /// <returns>all keys in this sybol table</returns>
        ///
        public IEnumerable <Key> Keys()
        {
            LinkedQueue <Key> queue = new LinkedQueue <Key>();

            for (int i = 0; i < M; i++)
            {
                if (keys[i] != null)
                {
                    queue.Enqueue((Key)keys[i]);
                }
            }
            return(queue);
        }
Example #15
0
        /// <summary>
        /// Returns all keys in the symbol table as an <c>IEnumerable</c>.
        /// To iterate over all of the keys in the symbol table named <c>st</c>,
        /// use the foreach notation: <c>foreach (Key key in st.Keys())</c>.</summary>
        /// <returns>all keys in the sybol table as an <c>IEnumerable</c></returns>
        ///
        public IEnumerable <Key> Keys()
        {
            LinkedQueue <Key> queue = new LinkedQueue <Key>();

            for (int i = 0; i < M; i++)
            {
                foreach (Key key in st[i].Keys())
                {
                    queue.Enqueue(key);
                }
            }
            return(queue);
        }
Example #16
0
        /// <summary>
        /// Returns the edges in a minimum spanning tree (or forest).</summary>
        /// <returns>the edges in a minimum spanning tree (or forest) as
        /// an iterable of edges</returns>
        ///
        public IEnumerable <Edge> Edges()
        {
            LinkedQueue <Edge> mst = new LinkedQueue <Edge>();

            for (int v = 0; v < edgeTo.Length; v++)
            {
                Edge e = edgeTo[v];
                if (e != null)
                {
                    mst.Enqueue(e);
                }
            }
            return(mst);
        }
Example #17
0
        /// <summary>
        /// Determines whether the edge-weighted digraph <c>G</c> has a
        /// topological order and, if so, finds such a topological order.</summary>
        /// <param name="G">the digraph</param>
        ///
        public TopologicalX(EdgeWeightedDigraph G)
        {
            // indegrees of remaining vertices
            int[] indegree = new int[G.V];
            for (int v = 0; v < G.V; v++)
            {
                indegree[v] = G.Indegree(v);
            }

            // initialize
            rank  = new int[G.V];
            order = new LinkedQueue <int>();
            int count = 0;

            // initialize queue to contain all vertices with indegree = 0
            LinkedQueue <int> queue = new LinkedQueue <int>();

            for (int v = 0; v < G.V; v++)
            {
                if (indegree[v] == 0)
                {
                    queue.Enqueue(v);
                }
            }

            for (int j = 0; !queue.IsEmpty; j++)
            {
                int v = queue.Dequeue();
                order.Enqueue(v);
                rank[v] = count++;
                foreach (DirectedEdge e in G.Adj(v))
                {
                    int w = e.To;
                    indegree[w]--;
                    if (indegree[w] == 0)
                    {
                        queue.Enqueue(w);
                    }
                }
            }

            // there is a directed cycle in subgraph of vertices with indegree >= 1.
            if (count != G.V)
            {
                order = null;
            }

            Debug.Assert(check(G));
        }
Example #18
0
        private void bfs(Graph G, int s)
        {
            LinkedQueue <int> q = new LinkedQueue <int>();

            color[s]  = WHITE;
            marked[s] = true;
            q.Enqueue(s);

            while (!q.IsEmpty)
            {
                int v = q.Dequeue();
                foreach (int w in G.Adj(v))
                {
                    if (!marked[w])
                    {
                        marked[w] = true;
                        edgeTo[w] = v;
                        color[w]  = !color[v];
                        q.Enqueue(w);
                    }
                    else if (color[w] == color[v])
                    {
                        isBipartite = false;

                        // to form odd cycle, consider s-v path and s-w path
                        // and let x be closest node to v and w common to two paths
                        // then (w-x path) + (x-v path) + (edge v-w) is an odd-length cycle
                        // Note: distTo[v] == distTo[w];
                        cycle = new LinkedQueue <int>();
                        LinkedStack <int> stack = new LinkedStack <int>();
                        int x = v, y = w;
                        while (x != y)
                        {
                            stack.Push(x);
                            cycle.Enqueue(y);
                            x = edgeTo[x];
                            y = edgeTo[y];
                        }
                        stack.Push(x);
                        while (!stack.IsEmpty)
                        {
                            cycle.Enqueue(stack.Pop());
                        }
                        cycle.Enqueue(w);
                        return;
                    }
                }
            }
        }
Example #19
0
 /// <summary>
 /// Determines a depth-first order for the edge-weighted digraph <c>G</c>.</summary>
 /// <param name="G">the edge-weighted digraph</param>
 ///
 public DepthFirstOrder(EdgeWeightedDigraph G)
 {
     pre       = new int[G.V];
     post      = new int[G.V];
     postorder = new LinkedQueue <int>();
     preorder  = new LinkedQueue <int>();
     marked    = new bool[G.V];
     for (int v = 0; v < G.V; v++)
     {
         if (!marked[v])
         {
             dfs(G, v);
         }
     }
 }
Example #20
0
File: TST.cs Project: zzhi/Algs4Net
 // all keys in subtrie rooted at x with given prefix
 private void collect(Node x, StringBuilder prefix, LinkedQueue <string> queue)
 {
     if (x == null)
     {
         return;
     }
     collect(x.left, prefix, queue);
     if (x.val != null)
     {
         queue.Enqueue(prefix.ToString() + x.c);
     }
     collect(x.mid, prefix.Append(x.c), queue);
     prefix.Remove(prefix.Length - 1, 1);
     collect(x.right, prefix, queue);
 }
Example #21
0
        private MinPQ <Edge> pq;        // edges with one endpoint in tree

        /// <summary>
        /// Compute a minimum spanning tree (or forest) of an edge-weighted graph.</summary>
        /// <param name="G">the edge-weighted graph</param>
        ///
        public LazyPrimMST(EdgeWeightedGraph G)
        {
            mst    = new LinkedQueue <Edge>();
            pq     = new MinPQ <Edge>();
            marked = new bool[G.V];
            for (int v = 0; v < G.V; v++) // run Prim from all vertices to
            {
                if (!marked[v])
                {
                    prim(G, v);         // get a minimum spanning forest
                }
            }
            // check optimality conditions
            Debug.Assert(check(G));
        }
Example #22
0
        /// <summary>
        /// Returns all keys in the symbol table in the given range,
        /// as an <c>IEnumerable</c>.</summary>
        /// <param name="lo">lower bound key</param>
        /// <param name="hi">upper bound key</param>
        /// <returns>all keys in the sybol table between <c>lo</c>
        ///        (inclusive) and <c>hi</c> (exclusive)</returns>
        /// <exception cref="ArgumentNullException" >if either <c>lo</c> or <c>hi</c>
        ///        is <c>null</c></exception>
        ///
        public IEnumerable <Key> Keys(Key lo, Key hi)
        {
            if (lo == null)
            {
                throw new ArgumentNullException("first argument to Keys() is null");
            }
            if (hi == null)
            {
                throw new ArgumentNullException("second argument to Keys() is null");
            }

            LinkedQueue <Key> queue = new LinkedQueue <Key>();

            keys(root, queue, lo, hi);
            return(queue);
        }
Example #23
0
File: TST.cs Project: zzhi/Algs4Net
        /// <summary>
        /// Returns all of the keys in the set that start with <c>prefix</c>.</summary>
        /// <param name="prefix">the prefix</param>
        /// <returns>all of the keys in the set that start with <c>prefix</c>
        /// as an iterable</returns>
        ///
        public IEnumerable <string> KeysWithPrefix(string prefix)
        {
            LinkedQueue <string> queue = new LinkedQueue <string>();
            Node x = get(root, prefix, 0);

            if (x == null)
            {
                return(queue);
            }
            if (x.val != null)
            {
                queue.Enqueue(prefix);
            }
            collect(x.mid, new StringBuilder(prefix), queue);
            return(queue);
        }
Example #24
0
        // is there an augmenting path?
        // an alternating path is a path whose edges belong alternately to the matching and not to the matching
        // an augmenting path is an alternating path that starts and ends at unmatched vertices
        //
        // if so, upon termination edgeTo[] contains a parent-link representation of such a path
        // if not, upon terminatation marked[] specifies the subset of vertices reachable via an alternating
        // path from one side of the bipartition
        //
        // this implementation finds a shortest augmenting path (fewest number of edges), though there
        // is no particular advantage to do so here
        private bool hasAugmentingPath(Graph G)
        {
            marked = new bool[numVertices];

            edgeTo = new int[numVertices];
            for (int v = 0; v < numVertices; v++)
            {
                edgeTo[v] = -1;
            }

            // breadth-first search (starting from all unmatched vertices on one side of bipartition)
            LinkedQueue <int> queue = new LinkedQueue <int>();

            for (int v = 0; v < numVertices; v++)
            {
                if (bipartition.Color(v) && !IsMatched(v))
                {
                    queue.Enqueue(v);
                    marked[v] = true;
                }
            }

            // run BFS, stopping as soon as an alternating path is found
            while (!queue.IsEmpty)
            {
                int v = queue.Dequeue();
                foreach (int w in G.Adj(v))
                {
                    // either (1) forward edge not in matching or (2) backward edge in matching
                    if (isResidualGraphEdge(v, w))
                    {
                        if (!marked[w])
                        {
                            edgeTo[w] = v;
                            marked[w] = true;
                            if (!IsMatched(w))
                            {
                                return(true);
                            }
                            queue.Enqueue(w);
                        }
                    }
                }
            }

            return(false);
        }
Example #25
0
        /// <summary>
        /// Returns all keys in the symbol table in the given range,
        /// as an <c>IEnumerable</c>.</summary>
        /// <param name="lo">lower bound key</param>
        /// <param name="hi">upper bound key</param>
        /// <returns>all keys in the sybol table between <c>lo</c></returns>
        ///   (inclusive) and <c>hi</c> (exclusive) as an <c>IEnumerable</c>
        /// <exception cref="ArgumentNullException">if either <c>lo</c> or <c>hi</c>
        ///   is <c>null</c></exception>
        ///
        public IEnumerable <Key> Keys(Key lo, Key hi)
        {
            if (lo == null)
            {
                throw new ArgumentNullException("first argument to keys() is null");
            }
            if (hi == null)
            {
                throw new ArgumentNullException("second argument to keys() is null");
            }

            LinkedQueue <Key> queue = new LinkedQueue <Key>();

            // if (IsEmpty || lo.CompareTo(hi) > 0) return queue;
            keys(root, queue, lo, hi);
            return(queue);
        }
Example #26
0
 private void collect(Node x, StringBuilder prefix, LinkedQueue <string> results)
 {
     if (x == null)
     {
         return;
     }
     if (x.Value != null)
     {
         results.Enqueue(prefix.ToString());
     }
     for (int i = 0; i < R; i++)
     {
         prefix.Append(alphabet.ToChar(i));
         collect(x[i], prefix, results);
         prefix.Remove(prefix.Length - 1, 1);
     }
 }
Example #27
0
        /// <summary>
        /// Returns the keys in the BST in level order (for debugging).</summary>
        /// <returns>the keys in the BST in level order traversal</returns>
        ///
        public IEnumerable <Key> LevelOrder()
        {
            LinkedQueue <Key>  keys  = new LinkedQueue <Key>();
            LinkedQueue <Node> queue = new LinkedQueue <Node>();

            queue.Enqueue(root);
            while (!queue.IsEmpty)
            {
                Node x = queue.Dequeue();
                if (x == null)
                {
                    continue;
                }
                keys.Enqueue(x.key);
                queue.Enqueue(x.left);
                queue.Enqueue(x.right);
            }
            return(keys);
        }
Example #28
0
        public static void MainTest(string[] args)
        {
            LinkedQueue <string> q     = new LinkedQueue <string>();
            TextInput            StdIn = new TextInput();

            while (!StdIn.IsEmpty)
            {
                string item = StdIn.ReadString();
                if (!item.Equals("-"))
                {
                    q.Enqueue(item);
                }
                else if (!q.IsEmpty)
                {
                    Console.Write(q.Dequeue() + " ");
                }
            }
            Console.WriteLine("(" + q.Count + " left on queue)");
        }
Example #29
0
        // add the keys between lo and hi in the subtree rooted at x
        // to the queue
        private void keys(Node x, LinkedQueue <Key> queue, Key lo, Key hi)
        {
            if (x == null)
            {
                return;
            }
            int cmplo = lo.CompareTo(x.key);
            int cmphi = hi.CompareTo(x.key);

            if (cmplo < 0)
            {
                keys(x.left, queue, lo, hi);
            }
            if (cmplo <= 0 && cmphi >= 0)
            {
                queue.Enqueue(x.key);
            }
            if (cmphi > 0)
            {
                keys(x.right, queue, lo, hi);
            }
        }
Example #30
0
        private IEnumerable <DirectedEdge> cycle; // negative cycle (or null if no such cycle)

        /// <summary>Computes a shortest paths tree from <c>s</c> to every other vertex in
        /// the edge-weighted digraph <c>G</c>.</summary>
        /// <param name="G">the acyclic digraph</param>
        /// <param name="s">the source vertex</param>
        /// <exception cref="ArgumentException">unless 0 &lt;= <c>s</c> &lt;= <c>V</c> - 1</exception>
        ///
        public BellmanFordSP(EdgeWeightedDigraph G, int s)
        {
            distTo  = new double[G.V];
            edgeTo  = new DirectedEdge[G.V];
            onQueue = new bool[G.V];
            for (int v = 0; v < G.V; v++)
            {
                distTo[v] = double.PositiveInfinity;
            }
            distTo[s] = 0.0;

            // Bellman-Ford algorithm
            queue = new LinkedQueue <int>();
            queue.Enqueue(s);
            onQueue[s] = true;
            while (!queue.IsEmpty && !HasNegativeCycle)
            {
                int v = queue.Dequeue();
                onQueue[v] = false;
                relax(G, v);
            }

            Debug.Assert(check(G, s));
        }