sharir kosaraju algorithm and vertices - algorithm

Let's say we run sharir kosaraju algorithm on a Directed graph. And we have an arc (u,v) on this graph.
In this algorithm we have two DFS passes.
Now suppose we insert vertex u into the first depth tree T.
Where can v appear? Is it in another tree created earlier or maybe later?
Thanks in advance !
I'm learning for a test... So this is a kind of homework I guess but I really have no clue!

Kosaraju's Algorithm is based on the fact that, Transpose of a Graph has the same number of Strongly Connected Components (SCCs) as the original Graph.
1) You have a graph G and an empty Stack S.
2) While S does not contain all the nodes in G, choose a random vertex u and do DFS on u. When you are done exploring a node v during this DFS, push the node v in S.
Back to your question, if there is an directed edge (u,v), v will be inserted in the stack S surely before u. But, there can be more nodes between insertion of v and insertion of u.
3) You do DFS of Transpose of G, by popping vertices from stack S, till S is empty. This will get you all the SCC's in the Graph G.

The wiki: http://en.wikipedia.org/wiki/Kosaraju%27s_algorithm is pretty instructive. I have implemented the algorithm and it is available here.
http://khanna111.com/wordPressBlog/2012/04/11/strongly-connected-components-of-a-graph/
The primary thing to understand is that the top elements in the stack in the first step after a pass would be the parents and that in the second step they would be popped out earlier and operate on the transpose where the nodes that were strongly connected in the original graph will remain strongly connected in the transpose.
The whole reason for the first pass is to get the parents to the top of the stack.

Related

How to traverse on only a cycle in a graph?

I'm attempting ch23 in CLRS on MSTs, here's a question:
Given a graph G and a minimum spanning tree T , suppose that we decrease the weight of one of the edges not in T . Give an algorithm for finding the minimum spanning tree in the modified graph.
A solution I found was to add this new changed edge in T, then exactly one simple cycle is created in T, traverse this cycle and delete the max-weight edge in this cycle, voila, the new updated MST is found!
My question is, how do I only traverse nodes on this simple-cycle? Since DFS/BFS traversals might go out of the cycle if I, say, start the traversal in T from one endpoint of this newly added edge in T.
One solution I could think of was to find the biconnected components in T after adding the new edge. Only one BCC will be found, which is this newly formed simple-cycle, then I can put in a special condition in my DFS code saying to only traverse edges/nodes in this BCC, and once a back-edge is found, stop the traversal.
Edit: graph G is connected and undirected btw
Your solution is basically good. To make it more formal you can use Tarjan's bridge-finding algorithm
This algorithm find the cut-edges (aka bridges) in the graph in linear time. Consider E' to be the cut-edges set. It is easy to prove that every edge in E' can not be on circle. So, E / E' are must be the cycle in the graph.
You can use hash-map or array build function to find the difference between your E and the cut-edges set
From here you can run simple for-loop to find the max weight edge which you want to remove.
Hope that help!

DFS on directed graph & Kosaraju's algorithm

I'm having trouble to understand Kosaraju's algorithm for finding the strongly connected components of a directed graph. Here's what I have on my notebook (I'm a student :D):
Start from an arbitrary vertex (label it with #1) and perform a DFS. When you can't go any further, label the last visited vertex with #2, and start another DFS (skipping vertices already labeled), and so on.
Transpose the graph.
Do DFS starting from each vertex in reverse order, those vertices which end visited after each DFS belong to the same SCC.
I have this example:
And after the first step starting from E, the labels are:
E
G
K
J
I
H
F
C
D
B
A
So here comes the thing: Is there a difference for DFS in directed/undirected graphs?
I did a mental test of the first step on my mind ignoring the arrows (just like it was undirected) and only got correct #1 for E (of course) and #2 for G, but #3 fell onto J, not K. So I thought maybe I should respect the arrows, and did a DFS considering that, but after the first pass starting from E, I can't go anywhere from G (which is #2), so I'm stuck there.
Is there anything about DFS on directed graphs that I'm not aware of? I've been taught DFS only on undirected graphs!
Your second step is incomplete. See Wikipedia:
Kosaraju's algorithm works as follows:
Let G be a directed graph and S be an empty stack.
While S does not contain all vertices:
Choose an arbitrary vertex v not in S. Perform a depth-first search starting at v. Each time that depth-first search finishes expanding a vertex u, push u onto S.
Reverse the directions of all arcs to obtain the transpose graph.
While S is nonempty:
Pop the top vertex v from S. Perform a depth-first search starting at v in the transpose graph. The set of visited vertices will give the strongly connected component containing v; record this and remove all these vertices from the graph G and the stack S. Equivalently, breadth-first search (BFS) can be used instead of depth-first search.
So you shouldn't only do something with the last vertex and first vertices, but with each vertex in the DFS.
Also note that you should be backtracking - when you can't go further, you go to the previous vertex and continue from there.
And no, you can't treat it as an undirected graph - the direction of the edges matter significantly.
So, starting from E, you'd, for example, go F, then G, then back to F, then H, then K, then I, then J, then back to I, K, H, F, and finally E, having pushed all visited vertices onto the stack.

Worst Case Time Complexity of Depth First Search

I know the answer to this particular question is O(V + E) and for a Graph like a tree, it makes sense because each Vertex is being explored once only.
However let's say there is a cycle in the graph.
For example, let's take up an undirected graph with four vertices A-B-C-D.
A is connected to both B and C, and Both B and C are connected to D. So there are four edges in total. A->B, A->C, B->D, C->D and vice versa.
Let's do DFS(A).
It will explore B first and B's neighbor D and D's neighbor C. After that C will not have any edges so it will come back to D and B and then A.
Then A will traverse its second edge and try to explore C and since it is already explored it will not do anything and DFS will end.
But over here Vertex "C" has been traversed twice, not once. Clearly worst case time complexity can be directly proportional to V.
Any ideas?
If you do not maintain a visited set, that you use to avoid revisitting already visited nodes, DFS is not O(V+E). In fact, it is not complete algorithm - thus it might not even find a path if there is a one, because it will be stuck in an infinite loop.
Note that for infinite graphs, if you are looking for a path from s to t, even with maintaining a visited set, it is not guaranteed to complete, since you might get stuck in an infinite branch.
If you are interested in keeping DFS's advantage of efficient space consumption, while still being complete - you might use iterative deepening DFS, but it will not trivially solve the problem if you are looking to discover the whole graph, and not a path to a specific node.
EDIT: DFS pseudo code with visited set.
DFS(v,visited):
for each u such that (v,u) is an edge:
if (u is not in visited):
visited.add(u)
DFS(u,visited)
It is easy to see that you invoke the recursion on a vertex if and only if it is not yet visited, thus the answer is indeed linear in the number of vertices and edges.
You can visit each vertex and edge of the graph a constant number of times and still be O(V+E). An alternative way of looking at it is that the cost is charged to the edge, not to the vertex.

Directed graph connectivity

Given a directed graph G, what is the best way to go about finding a vertex v such that there is a path from v to every other vertex in G?
This algorithm should run in linear time. Is there an existing algorithm that solves this? If not, I'd appreciate some insight into how this can be solved in linear time (I can only think of solutions that would certainly not take linear time).
Make a list L of all vertices.
Choose one; call it V. From V, walk the graph, removing points from the list as you go, and keeping a stack of unvisited edges. When you find a loop (some vertex you visit is not on the list), pop one of the edges from the stack and proceed.
If the stack is empty, and L is not empty, then choose a new vertex from L, call it V, and proceed as before.
When L is finally empty, the V you last chose is an answer.
This can be done in linear time in the number of edges.
Find the strongly connected components.
Condense each of the components into a single node.
Do a topological sort on the condensed graph, The node with the highest rank will have a path to each of the other nodes (if the graph is connected at all).
I think I've got a correct answer.
Get the SCC.
Condense each of the components into a single node.
Check whether every pair of adjacent nodes is reachable.
This is a sufficient and necessary condition.

What is the most efficient way to determine if a directed graph is singly connected?

I am working on an assignment where one of the problems asks to derive an algorithm to check if a directed graph G=(V,E) is singly connected (there is at most one simple path from u to v for all distinct vertices u,v of V.
Of course you can brute force check it, which is what I'm doing right now, but I want to know if there's a more efficient way. Could anyone point me in the right direction?
There is a better answer for this question. you can do that in O(|V|^2). and with more effort you can do it in linear time.
First you find strongly connected components of G. in each strong component, you search to find this cases:
1) if there is a forward edge in this component, it is not singly connected,
2) if there is a cross edge in this component, it is not singly connected,
3) if there are at least two back edges in tree rooted at vertex u, to proper ancestors of u, then it is not singly connected.
this can be done in O(E). ( I think except for case 3. I couldn't implement it well!! ).
If none of cases above occurred, you should check whether there is a cross edge or a forward edge on G^SCC ( graph G, with strong components replaced with single nodes), since we don't have backedges, it can be done by repeating dfs on each vertex of this graph in O(|V|^2).
Have you tried DFS.
Run DFS for every vertex in the graph as source
If a visited vertex is encountered again, the graph is not singly connected
repeat for every unvisited vertex.
The graph is singly connected.
Complexity O(v^2), o(v) dfs as no repetition.
I don't agree that its complexity will be O(V^2), as In DFS we don't call it for every vertex as see in Introduction to algorithm book also, syntax is DFS(G). We only call DFS for whole graph not for any single vertex unlike BFS. So here in this case according to me we have to check it by calling DFS once.If a visited vertex is encountered again, the graph is not singly connected(definitely we have to call it for every disconnected component but it already included in the code). SO the complexity will be O(V+E). As here E=V therefore complexity should be O(V).
I thought of this :
1) Run DFS from any vertex, if all vertices are covered in the DFS with no forward edges(there can be no cross as else not all vertices will be covered), then it can be a potential candidate.
2) If a vertex(level j) which is found in the DFS has a back edge to level i then no other vertex found after it should have a back edge toward any vertex with level less than j and every vertex much be reachable to the root(checked with second DFS).
This does it in linear time if this is correct.
Take a look at the definition of simple path. A cyclic graph can be singly connected. DFS won't work for A->B, B->A, which is singly connected.
The following paper uses strongly connected component to solve this.
https://www.cs.umd.edu/~samir/grant/khuller99.ps
Run DFS once from each vertex. The graph is singly connected if and
only if there are no forward edges and there are no cross edges within a
component.
Complexity : O(V.E)

Resources