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?
CodePudding user response:
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).
CodePudding user response:
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