Efficient algorithm to detect all 1-cuts in an undirected graph - algorithm

Given a connected graph G = (V, E), I want to find all of the 1-cuts. A 1-cut is just a single edge whose removal splits G into 2 connected components.
The algorithm I'm using right now is to remove each edge in turn and then use DFS to check whether its two endpoints are in the same connected component. The runs in O(E(V + E)) time. This is already faster than the best algorithm I can find in the min-cut literature from Nagamochi, Nishimura, and Ibaraki (1998), which takes O(VE(V + E)) time. Their algorithm is valid for all min-cuts of any size. I only need mine to be valid for 1-cuts.
Does anyone know of a better algorithm out there somewhere? Another feature of my use case that might be useful is that the graphs I work with tend to have very small feedback arc sets. If I had an algorithm whose run time depended on the size of a feedback arc set, that would also be useful.

Find all of the biconnected components in the graph (https://en.wikipedia.org/wiki/Biconnected_component). The wikipedia article outlines the classic Hopcroft/Tarjan algorithm that can do this in linear time.
Merge biconnected components that share a vertex, and then each edge that connects different components is a 1-cut.
The common name for a 1-cut is a bridge (https://en.wikipedia.org/wiki/Bridge_(graph_theory))

Related

Design a O(V+E) algorithm for determining at what point a graph becomes disconnected when deleting edges sequentially from a list of edges S

You are given a connected graph G and a series of edges S. One at a time, an edge from S is removed from G. You then check to see if G is still connected. If G is no longer connected, you return the edge. Otherwise, you remove the edge from the graph and continue.
My initial thought was to use Tarjan's bridge finding algorithm, which builds a DFS tree and then checks to see if a given vertex has a back-edge connecting one of its descendants to it or one of its ancestors. If it does not, then it is a bridge.
You can find all of the bridges in O(V+E) time while building the tree, but I am having problems adapting Tarjan's algorithm to account for deletions. Every time you delete an edge, the tree changes, and I am having trouble keeping the algorithm at O(V+E) time. Any thoughts?
You can do this fairly easily in almost-linear, O(E * alpha(V)) time, where alpha is the ridiculously-slowly-growing inverse-Ackermann function, using a disjoint-set data structure. The trick is to reverse S and add edges, so you ask about when G first becomes connected, rather than disconnected. The incremental connectivity problem is quite a bit easier than the decremental connectivity case.
Given an implementation of disjoint-set, you can augment it to track the number of components, and a graph is connected exactly when there is only one component. If you start with n components, then before any Union(x, y) operation, check whether x and y belong to the same component. If they don't, then the union operation will reduce the graph's components by 1.
For your graph, you'll need to preprocess S to find all of the edges in G that are not in S, and add these to the disjoint-set data structure first. Then, if adding S[i] causes the graph to be connected for the first time, the answer is i, since we've already added S[i+1], S[i+2], ... S[n-1].
Optimal Complexity
The inverse-Ackermann function is at most 4 for any input that fits in our universe, so our Union-find algorithm is usually considered 'pretty much linear'. However, if that's not good enough...
You can do this in O(V+E), although it's quite complex, and probably of mostly theoretical interest. Gabow and Tarjan's 1984 paper found an algorithm that supports Union-Find in O(1) amortized cost per operation if we know the order of all union operations, which we do here. It still uses the disjoint-set data structure, but adds additional auxiliary structures to cache node information on small sets.
Some pseudocode is provided in the paper, but you'll probably need to implement this yourself or look for implementations online. It also only works in the word RAM model, since it fundamentally relies on manipulating small bit-strings in constant time to use them as lookup tables (a fairly standard assumption, but you'll need to do some low-level bit manipulation).
Find the bridge edges
FOR E in S
IF E is a bridge
STOP
remove E
IF E1 is disconnected ( zero edges on E1 )
STOP
IF E2 is disconnected
STOP
E1 and E2 are the vertices connected by E

Efficient way to check whether a graph has become disconnected?

Using a disjoint set forest, we can efficiently check incrementally whether a graph has become connected while adding edges to it. (Or rather, it allows us to check whether two vertices already belong to the same connected component.) This is useful, for example, in Kruskal's algorithm for computing the minimum spanning tree.
Is there a similarly efficient data structure and algorithm to check whether a graph has become disconnected while removing edges from it?
More formally, I have a connected graph G = (V, E) from which I'm iteratively removing edges one by one. Without loss of generality, let's say these are e_1, e_2, and so on. I want to stop right before G becomes disconnected, so I need a way to check whether the removal of e_i will make the graph disconnected. This can of course be done by removing e_i and then doing a breadth-first or depth-first search from an arbitrary vertex, but this is an O(|E|) operation, making the entire algorithm O(|E|²). I'm hoping there is a faster way by somehow leveraging results from the previous iteration.
I've looked at partition refinement but it doesn't quite solve this problem.
There’s a family of data structures that are designed to support queries of the form “add an edge between two nodes,” “delete an edge between two nodes,” and “is there a path from node x to node y?” This is called the dynamic connectivity problem and there are many data structures that you can use to solve it. Unfortunately, these data structures tend to be much more complicated than a disjoint-set forest, so you may want to search around to see if you can find a ready-made implementation somewhere.
The layered forest structure of Holm et al works by maintaining a hierarchy of spanning forests for the graph and doing some clever bookkeeping with edges to avoid rescanning them when seeing if two parts of the graph are still linked. It supports adding and deleting edges in amortized time O(log2 n) and queries of the form “are these two nodes connected?” in time O(log n / log log n).
A more recent randomized structure called the randomized cutset was developed by Kapron et al. It has worst-case O(log5 n) costs for all three operations (IIRC).
There might be a better way to solve your particular problem that doesn’t require these heavyweight approaches, but I figured I’d mention these in case they’re helpful.

Pairs of Vertices Unreachable from Each Other in a Directed Graph

I am requested to design an algorithm to determine whether there exists any pair of vertices unreachable from each other in a directed graph. The algorithm must run in O(|V| + |E|) time
Meaning: vertex i cannot reach vertex j, and vertex j cannot reach vertex i.
I have read about the method for finding strongly connected components, I wonder whether or not I can start from there and devise an algorithm usable under the current circumstance?
If you can find all strongly connected components in the linear O(V + E) time requested then you are done. This may seem a bit overkill but it solves the problem. To find all strongly connected components, assuming your graph is represented as an adjacency list, perhaps the simplest O(V + E) linear time algorithm is Kosaraju's, see e.g. http://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
Once you find all strongly connected components, then it is fairly simple to test whether there is a pair of strongly connected components that is not connected by any path, by considering the condensed graph where nodes are strongly connected components and an edge exists if there is an edge between any two nodes chosen from the two connected components.
Here are a few hints to help you get started:
Try solving this problem first when the graph you're given is a DAG. What does the structure of the DAG have to be in order for any pair of nodes to be at least weakly connected?
If you compute the strongly-connected components of a graph, those SCCs themselves form a DAG. Could you use this observation, in conjunction with your algorithm for part (1), to form an algorithm that works on arbitrary graphs?
Hope this helps!
If you are able to find the strongly connected components then you conversely know the vertices that are not connected as well.
The wiki: http://en.wikipedia.org/wiki/Kosaraju%27s_algorithm is pretty instructive. I have implemented the algorithm and it is available here. Runs in O (v + E ). We are assuming that the graph is backed as an adjacency list.
Link for Kosaraju Implementation in Java
Try it out, hopefully you would find no bugs :-)

Checking for outerplanarity in graph using BOOST?

I just conceptualy want to know how to check if a graph is outerplanar or not. I know you can check for planarity in graph using BOOST, how do you check for outerplanarity? hints?
Perhaps a bit too late to answer, but I hope this will still help you or anyone else stumbling upon this question.
To this day Boost still doesn't have any outerplanarity testing algorithm implemented, but it's actually quite simple to check for outerplanarity using Boost's planarity checks.
According to Manfred Wiegers' Recognizing outerplanar graphs in linear time article:
a graph G is outerplanar iff K1 + G (a new vertex is joined with all vertices of G) is planar.
So you need to add an additional vertex to the graph with edges connecting it to all vertices of the original graph and then check if the new graph is planar. If so, then the original graph is outerplanar.
Also note that each outerplanar graph with n vertices has less than 2n − 3 edges. Adding this edge count check could quickly filter out many obviously non-outerplanar graphs.

Creating a graph and finding strongly connected components in a single pass (not just Tarjan!)

I have a particular problem where each vertex of a directed graph has exactly four outward-pointing paths (which can point back to the same vertex).
At the beginning, I have only the starting vertex and I use DFS to discover/enumerate all the vertices and edges.
I can then use something like Tarjan's algo to break the graph into strongly connected components.
My question is, is there a more efficient way to doing this than discovering the graph and then applying an algorithm. For example, is there a way of combining the two parts to make them more efficient?
To avoid having to "discover" the graph at the outset, the key property that Tarjan's algorithm would need is that, at any point in its execution, it should only depend on the subgraph it has explored so far, and it should only ever extend this explored region by enumerating the neighbours of some already-visited vertex. (If, for example, it required knowing the total number of nodes or edges in the graph at the outset, then you would be sunk.) From looking at the Wikipedia page it seems that the algorithm does indeed have this property, so no, you don't need to perform a separate discovery phase at the start -- you can discover each vertex "lazily" at the lines for each (v, w) in E do (enumerate all neighbours of v just as you currently do in your discovery DFS) and for each v in V do (just pick v to be any vertex you have already discovered as a w in the previous step, but which you haven't yet visited yet with a call to strongconnect(v)).
That said, since your initial DFS discovery phase only takes linear time anyway, I'd be surprised if eliminating it sped things up much. If your graph is so large that it doesn't fit in cache, it could halve the total time, though.

Resources