private void dfs(Digraph G, int v) { marked[v] = true; preorder[v] = pre++; stack1.Push(v); stack2.Push(v); foreach (int w in G.Adj(v)) { if (!marked[w]) { dfs(G, w); } else if (id[w] == -1) { while (preorder[stack2.Peek()] > preorder[w]) { stack2.Pop(); } } } // found strong component containing v if (stack2.Peek() == v) { stack2.Pop(); int w; do { w = stack1.Pop(); id[w] = count; } while (w != v); count++; } }
private readonly int s; // source vertex /// <summary> /// Computes the vertices connected to the source vertex <c>s</c> in the graph <c>G</c>.</summary> /// <param name="G">the graph</param> /// <param name="s">the source vertex</param> /// public NonrecursiveDFS(Graph G, int s) { this.s = s; marked = new bool[G.V]; edgeTo = new int[G.V]; // to be able to iterate over each adjacency list, keeping track of which // vertex in each adjacency list needs to be explored next IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // depth-first search using an explicit stack LinkedStack <int> stack = new LinkedStack <int>(); marked[s] = true; stack.Push(s); //Console.Write("Visiting ({0})\n", s); while (!stack.IsEmpty) { int v = stack.Peek(); if (adj[v].MoveNext()) { int w = adj[v].Current; //Console.Write("Approaching {0}\n", w); if (!marked[w]) { // discovered vertex w for the first time marked[w] = true; edgeTo[w] = v; stack.Push(w); //Console.Write("Visiting ({0})\n", w); } //else // Console.Write("Visited {0}\n", w); } else { //Console.Write("Returning from {0}\n", stack.Peek()); stack.Pop(); } } }
private bool[] marked; // marked[v] = is there an s->v path? /// <summary> /// Computes the vertices reachable from the source vertex <c>s</c> in the /// digraph <c>G</c>.</summary> /// <param name="G">the digraph</param> /// <param name="s">the source vertex</param> /// public NonrecursiveDirectedDFS(Digraph G, int s) { marked = new bool[G.V]; // to be able to iterate over each adjacency list, keeping track of which // vertex in each adjacency list needs to be explored next IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // depth-first search using an explicit stack LinkedStack <int> stack = new LinkedStack <int>(); marked[s] = true; stack.Push(s); while (!stack.IsEmpty) { int v = stack.Peek(); if (adj[v].MoveNext()) { int w = adj[v].Current; // Console.Write("check {0}\n", w); if (!marked[w]) { // discovered vertex w for the first time marked[w] = true; // edgeTo[w] = v; stack.Push(w); // Console.Write("dfs({0})\n", w); } } else { // Console.Write("{0} done\n", v); stack.Pop(); } } }
/// <summary> /// Computes the convex hull of the specified array of points. /// </summary> /// <param name="pts">the array of points</param> /// <exception cref="NullReferenceException">if <c>points</c> is <c>null</c> or if any /// entry in <c>points[]</c> is <c>null</c></exception> /// public GrahamScan(Point2D[] pts) { // defensive copy int N = pts.Length; Point2D[] points = new Point2D[N]; for (int i = 0; i < N; i++) { points[i] = pts[i]; } // preprocess so that points[0] has lowest y-coordinate; break ties by x-coordinate // points[0] is an extreme point of the convex hull // (alternatively, could do easily in linear time) Array.Sort(points); // sort by polar angle with respect to base point points[0], // breaking ties by distance to points[0] Array.Sort(points, 1, N - 1, points[0].GetPolarOrder()); hull.Push(points[0]); // p[0] is first extreme point // find index k1 of first point not equal to points[0] int k1; for (k1 = 1; k1 < N; k1++) { if (!points[0].Equals(points[k1])) { break; } } if (k1 == N) { return; // all points equal } // find index k2 of first point not collinear with points[0] and points[k1] int k2; for (k2 = k1 + 1; k2 < N; k2++) { if (Point2D.Ccw(points[0], points[k1], points[k2]) != 0) { break; } } hull.Push(points[k2 - 1]); // points[k2-1] is second extreme point // Graham scan; note that points[N-1] is extreme point different from points[0] for (int i = k2; i < N; i++) { Point2D top = hull.Pop(); while (Point2D.Ccw(hull.Peek(), top, points[i]) <= 0) { top = hull.Pop(); } hull.Push(top); hull.Push(points[i]); } Debug.Assert(isConvex()); }
private int[] distTo; // distTo[v] = number of edges on shortest path to v /// <summary> /// Determines a maximum matching (and a minimum vertex cover) /// in a bipartite graph.</summary> /// <param name="G">the bipartite graph</param> /// <exception cref="ArgumentException">if <c>G</c> is not bipartite</exception> /// public HopcroftKarp(Graph G) { bipartition = new BipartiteX(G); if (!bipartition.IsBipartite) { throw new ArgumentException("graph is not bipartite"); } // initialize empty matching this.V = G.V; mate = new int[V]; for (int v = 0; v < V; v++) { mate[v] = UNMATCHED; } // the call to hasAugmentingPath() provides enough info to reconstruct level graph while (hasAugmentingPath(G)) { // to be able to iterate over each adjacency list, keeping track of which // vertex in each adjacency list needs to be explored next IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // for each unmatched vertex s on one side of bipartition for (int s = 0; s < V; s++) { if (IsMatched(s) || !bipartition.Color(s)) { continue; // or use distTo[s] == 0 } // find augmenting path from s using nonrecursive DFS LinkedStack <int> path = new LinkedStack <int>(); path.Push(s); while (!path.IsEmpty) { int v = path.Peek(); // retreat, no more edges in level graph leaving v if (!adj[v].MoveNext()) { path.Pop(); } // advance else { // process edge v-w only if it is an edge in level graph int w = adj[v].Current; if (!isLevelGraphEdge(v, w)) { continue; } // add w to augmenting path path.Push(w); // augmenting path found: update the matching if (!IsMatched(w)) { // Console.WriteLine("augmenting path: " + toString(path)); while (!path.IsEmpty) { int x = path.Pop(); int y = path.Pop(); mate[x] = y; mate[y] = x; } cardinality++; } } } } } // also find a min vertex cover inMinVertexCover = new bool[V]; for (int v = 0; v < V; v++) { if (bipartition.Color(v) && !marked[v]) { inMinVertexCover[v] = true; } if (!bipartition.Color(v) && marked[v]) { inMinVertexCover[v] = true; } } Debug.Assert(certifySolution(G)); }