/// <summary> /// We cannot use the same method as we used for undirected graphs /// We can use Kosaraju’s DFS based simple algorithm with 2 DFS passes /// Steps are as follows: /// 1. Initialize all vertices' isvisited as false /// 2. Do DFS on an arbitarily selected vertex v. If all the vertices is not visited return false /// 3. Initialize all vertices' isvisited as false /// 4. Reverse all the edges of the graph /// 5. Do DFS on the same vertex v. If all the vertices are not visited return false. /// Return true /// /// /// The running time here is O(V+E) /// </summary> /// <param name="udg"></param> /// <returns></returns> public bool IsDirectedGraphStronglyConnected(DirectedGraphWithVertexDictionary dg) { if (dg.AllVertices.Values.Count == 0) { // error condition throw new ArgumentException("The graph is empty"); } // 1. Initialize all vertices' isvisited as false foreach (GraphVertex vertex in dg.AllVertices.Values) { vertex.IsVisited = false; } // select the arbitrary vertex GraphVertex arbVertex = dg.AllVertices.Values.ElementAt(0); //2. Do DFS on an arbitarily selected vertex v. If all the vertices is not visited return false DFS(arbVertex); foreach (GraphVertex vertex in dg.AllVertices.Values) { if (!vertex.IsVisited) { return(false); } } //3.Initialize all vertices' isvisited as false foreach (GraphVertex vertex in dg.AllVertices.Values) { vertex.IsVisited = false; } //4. Reverse all the edges of the graph dg = dg.ReverseDirectedGraphWithVertexDictionary(); // 5. Do DFS on the same vertex v. If all the vertices are not visited return false. DFS(dg.AllVertices[arbVertex.Data]); foreach (GraphVertex vertex in dg.AllVertices.Values) { if (!vertex.IsVisited) { return(false); } } return(true); }
public SnakeAndLadder(int sAndLBoardLength, List <GraphEdge> snakesAndLadders) { Board = new DirectedGraphWithVertexDictionary(); for (int i = 1; i <= sAndLBoardLength; i++) { for (int j = 1; j <= 6 && i + j <= sAndLBoardLength; j++) // This represents the different outcomes of the dice throw { // i+j<= sAndLBoardLength handles the overflow(from the board) corner case Board.AddEdge(i, i + j); } } foreach (GraphEdge edge in snakesAndLadders) { Board.MergeVertex(edge.StartEdgeId, edge.EndEdgeId); } }
public static void TestStronglyConnectedGraph() { StronglyConnectedGraph scg = new StronglyConnectedGraph(); UndirectedGraph notStronglyConnected = GraphProbHelper.CreateUndirectedGraphNotStronglyConnected(); Console.WriteLine("The graph is strongly connected. Expected: False, Actual: {0}", scg.IsUndirectedGraphStronglyConnected(notStronglyConnected)); UndirectedGraph stronglyConnected = GraphProbHelper.CreateUndirectedGraphStronglyConnected(); Console.WriteLine("The graph is strongly connected. Expected: True, Actual: {0}", scg.IsUndirectedGraphStronglyConnected(stronglyConnected)); DirectedGraphWithVertexDictionary dg = GraphProbHelper.CreateDirectedGraphWithVertexDictStronglyConnected(); Console.WriteLine("The graph is strongly connected. Expected: True, Actual: {0}", scg.IsDirectedGraphStronglyConnected(dg)); dg = GraphProbHelper.CreateDirectedGraphWithVertexDictNotStronglyConnected(); Console.WriteLine("The graph is strongly connected. Expected: False, Actual: {0}", scg.IsDirectedGraphStronglyConnected(dg)); }
public static DirectedGraphWithVertexDictionary ReverseDirectedGraphWithVertexDictionary(this DirectedGraphWithVertexDictionary dg) { // Add all edges to this dictionary where for an edge u->v add it as dict[v].Add(u) Dictionary <GraphVertex, List <GraphVertex> > allVertices = new Dictionary <GraphVertex, List <GraphVertex> >(); foreach (GraphVertex vertex in dg.AllVertices.Values) { if (vertex.NeighbourVertices != null) { foreach (GraphVertex neighbour in vertex.NeighbourVertices) { if (!allVertices.ContainsKey(neighbour)) { allVertices.Add(neighbour, new List <GraphVertex> { vertex }); } else { allVertices[neighbour].Add(vertex); } } } } // Make the changes to all the vertices in the directed graph foreach (GraphVertex vertex in dg.AllVertices.Values) { if (allVertices.ContainsKey(vertex)) { vertex.NeighbourVertices = allVertices[vertex]; } else { vertex.NeighbourVertices = null; } } return(dg); }