How do you find out whether an undirected graph is Biconnected or not using its depth first search traversal.
Is there any other way than traversing the whole graph to find disconnected pieces of the graph.
You calculate the low(v) for every vertex in linear time (i.e. during the execution of the DFS). And there exists a bridge (i.e. an edge whose removal will disconnect the graph ==> not biconnected) iff there's a non-root vertex whose low value is itself OR if the root has more than one child.
It's explained here on point 5.2 http://www.cse.ohio-state.edu/~lai/780/graph.pdf
I have no answer to this, but my gut feeling would suggest that you would have to do the depth first search traversal as the biconnected property of the graph is a property of the whole graph and not any subset of the graph.
Related
I’m familiar with the Hamilton path for a directed graph - visit every node exactly once.
I’m looking for an algorithm to walk the graph so that I visit every node at least once. I can’t find the standard name for this problem, if any.
This graph is walkable - root-a-d-b-c
This graph is not walkable - because in my walk, if I reach c, I have no directed edge to reach a & d and conversely, if I walk to a, d; there’s no directed edge that takes me to b & c
Hope that clarifies the question? Is there a standard name for this type of graph walk and an algorithm to solve it?
Hamiltonian path
Finding at most 2 leafs in the graph
I don't know if there's a name for a directed "walkable" graph, but it's not too hard to determine of a graph is walkable or not:
Find all the strongly connected components using Tarjan's algorithn, for example
Make a new directed graph of the connections between SCCs. This will be a DAG, and your original graph is walkable if and only if this DAG is walkable.
To determine whether or not a DAG is walkable, do a topological sort. Then check that each vertex has an edge to the next.
Each of these steps takes linear time, so you get O(|V|+|E|) complexity for the whole algorithm.
Theorem: a directed graph is walkable if and only if its strongly connected components are totally ordered by reachability.
Proof sketch: (walkable implies condition) The existence of a walk implies that, for each two strongly connected components, a vertex from one or the other appears first in the walk. That component can reach the other. (condition implies walkable) Since there is full connectivity inside a strongly connected component, each is walkable on its own. We just have to concatenate the walks according to the total order, adding the necessary transitions.
The proof is constructive, so we can extract an algorithm.
Algorithm
Compute the strongly connected components.
Concatenate the strongly connected components in topological order. Actually Tarjan's algorithm will list them in reverse topological order, so this doesn't need to be a separate step.
For each adjacent pair in the previous list, use breadth-first search to find a shortest path.
In general, this algorithm does not find the shortest walk (that's NP-hard by reduction from Hamiltonian path).
I know the brute force approach for solving this problem which can be given as:
Iterate over all edges
Take a set(or list)(suppose s)
if adding an edge to s doesn't make a cycle then add edge to s
End if iteration is complete over all edges.
But I want an efficient solution(time+space both) for this problem.
So, Any help will be appreciated...........
Assuming that the graph is connected (otherwise no spanning tree exists): Beginning from some arbitrary vertex, perform depth-first search in the graph, recording for each vertex whether it has been visited already, and outputting every edge to an unvisited vertex that you come across. These edges comprise a spanning tree since they are cycle-free and visit every vertex.
This takes O(|V|+|E|) time and O(|V|) space.
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!
Although we can check a if a graph is bipartite using BFS and DFS (2 coloring ) on any given undirected graph, Same implementation may not work for the directed graph.
So for testing same on directed graph , Am building a new undirected graph G2 using my source graph G1, such that for every edge E[u -> v] am adding an edge [u,v] in G2.
So by applying a 2 coloring BFS I can now find if G2 is bipartite or not.
and same applies for the G1 since these two are structurally same. But this method is costly as am using extra space for graph. Though this will suffice my purpose as of now, I'd like know if there any better implementations for the same.
Thanks In advance.
You can execute the algorithm to find the 2-partition of an undirected graph on a directed graph as well, you just need a little twist. (BTW, in the algorithm below I assume that you will eventually find a 2-coloring. If not, then you will run into a node that is already colored and you find you need to color it to the other color. Then you just exit saying it's not bipartite.)
Start from any node and do the 2-coloring by traversing the edges. If you have traversed every edge and every node in the graph then you have your partition. If not, then you have a component that is 2-colored and there are no edges leaving the component. Pick any node not in the component and repeat. If you get into a situation when you have a few components that are all 2-colored, and there are no edges leaving any of them, and you encounter an edge that originates in a node in the component you are currently building and goes into a node in one of the previous components then you just merge the current component with the older one (and possibly need to flip the color of every node in one of the components -- flip it in the smaller component). After merging just continue. You can do the merge, because at the time of the merge you have scanned only one edge between the two components, so flipping the coloring of one of the components leaves you in a valid state.
The time complexity is still O(max(|N|,|E|)), and all you need is an extra field for every node indicating which component that node is in.
Given a general undirected graph, how can we print all the biconnected components of the graph in O(N+M) time? I know Tarjan's algorithm that is used to output all the articulation points of an undirected graph but I am finding it hard to extend the algorithm to print the biconnected components. I tried searching google but all the results that I got are not working on my test cases as they miss out on edge cases of the algorithm.
Can someone please provide working code for this problem.
Def: A biconnected component is a connected subgraph containing no vertex whose deletion would disconnect the subgraph.
Edit: I have successfully implemented the algorithm as described in this link provided by Niklas. Now I have a different question, how can I find out sub graphs of an undirected graph containing no edge whose deletion would disconnect the subgraph. Please help me solve this alternate problem as well.
It's a classical problem with a known linear-time algorithm. You will probably need to decompose the graph into connected components first, though. Algorithm description from Wikipedia:
The classic sequential algorithm for computing biconnected components
in a connected undirected graph due to John Hopcroft andRobert
Tarjan (1973) [1] runs in linear time, and is based on depth-first
search. This algorithm is also outlined as Problem 22-2 of Introduction
to Algorithms (both 2nd and 3rd editions). The idea is to run a
depth-first search while maintaining the following information:
the depth of each vertex in the depth-first-search tree (once it gets
visited), and for each vertex v, the lowest depth of neighbors of all
descendants of v in the depth-first-search tree, called
the lowpoint. The depth is standard to maintain during a depth-first
search. The lowpoint of v can be computed after visiting all
descendants of v (i.e., just before v gets popped off the
depth-first-search stack) as the minimum of the depth of v, the depth
of all neighbors of v (other than the parent of v in the
depth-first-search tree) and the lowpoint of all children of v in the
depth-first-search tree. The key fact is that a nonroot vertex v is a
cut vertex (or articulation point) separating two biconnected
components if and only if there is a child y of v such that
lowpoint(y) ≥ depth(v). This property can be tested once the
depth-first search returned from every child of v (i.e., just
before v gets popped off the depth-first-search stack), and if
true, v separates the graph into different biconnected components.
This can be represented by computing one biconnected component out of
every such y (a component which contains y will contain the subtree
of y, plus v), and then erasing the subtree of y from the tree.The
root vertex must be handled separately: it is a cut vertex if and only
if it has at least two children. Thus, it suffices to simply build one
component out of each child subtree of the root (including the root).
A good pseudo-code implementation can be found at http://www.cs.umd.edu/class/fall2005/cmsc451/biconcomps.pdf.
Have a look at this PhD thesis on Planarity Testing by Path Addition.
Chapter 5 gives pseudo code for a DFS algorithm (two versions using recursion or iteration) and an algorithm to partition (decompose) the DFS tree (also known as a Tremaux tree) into a hierarchy of path segments (or chains). Chapter 4 gives a classification of these path segments into 4 different types depending on where the tail of the path segment connects in the DFS tree (relative to the path segment's head).
Given this separation, you can partition the tree into biconnected components such that:
Class 1 path segments are not part of any biconnected component;
Class 2 (minus the edges & vertices succeeding the segment's head and preceding the tail which, like Class 1 segments, are not part of any biconnected component) and Class 3 path segments form a loop and are at the start (root) of a biconnected component; and
Class 4 segments are part of a biconnected component which contains their most recent Class 2 or 3 ancestor path segment.
If correctly done, you should be able to extract these biconnected components in O(V+E) time.
There is Java source code at the back of the thesis which does a full planarity test in O(V+E) time & memory which may give you some further pointers (and extracts all permutations P of embeddings of the biconnected components in O(P(V+E))).