Kruskal's Algorithm: Update MST when an edge becomes mandatory - algorithm

It is given an undirected graph G = (V, E). First it is asked what is the cost of MST.
I can easily find out using Kruskall algorithm, like this:
G = (V, E)
for each edge (u, v) in E sorted by wight
{
if(Find(u) != Find(v))
{
Add (u, v) to the MST
Union(u, v); // put u and v in the same set
}
}
After that, for each edge in the initial graph, it is asked what will the cost of new MST it that edge shall be present in the Minimum Spanning Tree.
If an edge is already present in the MST, the answer remains the same. Otherwise, I can run Kruskall once again. The pseudocode is the following:
G = (V, E)
G1 = runKruskall(G)
for each edge (u, v) in E
{
ClearUnionSets()
if (u, v) in G1
{
print costOf(G1)
} else {
Union(u, v)
G2 = runKruskall(G)
print costOf(G2)
}
}
The problem with that approach is that the total complexity would be: O(E*E)
My question is if there exist a better solution for updating MST as described above.
What I was thinking is that when running for the first time Kruskall, for every edge (u, v), were u and v are in the same set, find the the maximum weighted edge already present in the partial MST that makes a cycle with (u, v) and store that information in a matrix M at M[u][v]. Doing this, the problem of updating MST when a edge becomes mandatory would be solved in O(1).
Can anyone help me with this?

For every edge u-v that is not on the MST, the smallest spanning tree including the edge is the one where u-v replaces the largest edge on the path from u to v on the MST.
The edge to be replaced can be found efficiently as follows. First, root the MST at an arbitrary vertex. We will modify the algorithm to find the lowest common ancestor (LCA) of two vertices, described here. In addition to storing the 2^i th parent for each vertex, we will also store the largest edge on the path to the 2^i th parent. Using this array, while we calculate the LCA we will also calculate the largest edge on the path to the LCA, which gives us the largest edge on the path between the two vertices.
Preprocessing involves finding the MST in O(E log E) and building the parent table for LCA in O(N log N), with the requirement of O(N log N) space. After this, finding the modified MST for each edge requires only the evaluation of LCA once, which can be performed in O(log N). Thus the total complexity is only O(E log E).

Related

Vertex Cover of a Tree Linear or Polynomial Time?

I have the following algorithm to find the minimum vertex cover of a tree. That is a minimal sized set S of vertices such that for every edge (v,u) in G either v is in S or u is in S.
I have been told the algorithm has linear time complexity, however I don't understand how this is the case, since isn't the number of edges incident to u of the order O(n) and so the complexity would be O(n^2)?
Let T = <V, E> be a Tree. That is, the vertex set is V, the edge set is E. Also suppose the cover set = C. The algorithm can be described as follows:
while V != [] do
Identify a leaf vertex v
Locate u = parent(v), the parent vertex of v.
Add u to C
Remove all the edges incident to u
return C.
In a tree, |E| = |V| - 1, so there are O(n) edges to deal with in total.

very hard and elegant question on shortest path

Given a weighed, connected and directed graph G=(V,E) with n vertexes and m edges, and given a pre-calculated shortest path distance's matrix S where S is n*n S(i,j) denotes the weight of shortest path from vertex i to vertex j.
we know just weight of one edge (u, v) is changed (increased or decreased).
for two specific vertex s and t we want to update the shortest path length between these two vertex.
This can be done in O(1).
How is this possible? what is the trick of this answer?
You certainly can for decreases. I assume S will always refer to the old distances. Let l be the new distance between (u, v). Check if
S(s, u) + l + S(v, t) < S(s, t)
if yes then the left hand side is the new optimal distance between s and t.
Increases are impossible. Consider the following graph (edges in red have zero weight):
Suppose m is the minimum weight edge here, except for (u, v) which used to be lower. Now we update (u, v) to some weight l > m. This means we must find m to find the new optimum length.
Suppose we could do this in O(1) time. Then it means we could find the minimum of any array in O(1) time by feeding it into this algorithm after adding (u, v) with weight -BIGNUMBER and then 'updating' it to BIGNUMBER (we can lazily construct the distance matrix because all distances are either 0, inf or just the edge weights). That is clearly not possible, thus we can't solve this problem in O(1) either.

Shortest path distance from source(s) to all nodes in the graph - O(m + n log(n)) time

Let G(V,E) be a directed weighted graph with edge lengths, where all of the edge lengths are positive except two of the edges have negative lengths. Given a fixed vertex s, give an algorithm computing shortest paths from s to any other vertex in O(e + v log(v)) time.
My work:
I am thinking about using the reweighting technique of Johnson's algorithm. And then, run Belford Algo once and apply Dijkstra v times. This will give me the time complexity as O(v^2 log v + ve).
This is the standard all pair shortest problem, As I only need one vertex (s) - my time complexity will be O(v log v + e) right?
For this kind of problem, changing the graph is often a lot easier than changing the algorithm. Let's call the two negative-weight edges N1 and N2; a path by definition cannot use the same edge more than once, so there are four kinds of path:
A. Those which use neither N1 nor N2,
B. Those which use N1 but not N2,
C. Those which use N2 but not N1,
D. Those which use both N1 and N2.
So we can construct a new graph with four copies of each node from the original graph, such that for each node u in the original graph, (u, A), (u, B), (u, C) and (u, D) are nodes in the new graph. The edges in the new graph are as follows:
For each positive weight edge u-v in the original graph, there are four copies of this edge in the new graph, (u, A)-(v, A) ... (u, D)-(v, D). Each edge in the new graph has the same weight as the corresponding edge in the original graph.
For the first negative-weight edge (N1), there are two copies of this edge in the new graph; one from layer A to layer B, and one from layer C to layer D. These new edges have weight 0.
For the second negative-weight edge (N2), there are two copies of this edge in the new graph; one from layer A to layer C, and one from layer B to layer D. These new edges have weight 0.
Now we can run any standard single-source shortest-path problem, e.g. Dijkstra's algorithm, just once on the new graph. The shortest path from the source to a node u in the original graph will be one of the following four paths in the new graph, whichever corresponds to a path of the lowest weight in the original graph:
(source, A) to (u, A) with the same weight.
(source, A) to (u, B) with the weight in the new graph minus the weight of N1.
(source, A) to (u, C) with the weight in the new graph minus the weight of N2.
(source, A) to (u, D) with the weight in the new graph minus the weights of N1 and N2.
Since the new graph has 4V vertices and 4E - 2 edges, the worst-case performance of Dijkstra's algorithm is O((4E - 2) + 4V log 4V), which simplifies to O(E + V log V) as required.
To ensure that a shortest path in the new graph corresponds to a genuine path in the original graph, it remains to be proved that a path from e.g. (source, A) to (u, B) will not use two copies of the same edge from the original graph. That is quite easy to show, but I'll leave it to you as something to think about.

Algorithm to Compute square of a directed graph(represented in form of an adjacency list)

I am working on constructing an algorithm to compute G^2 of a directed graph that is a form of an adjacency list, where G^2 = (V,E'), where E' is defined as (u,v)∈E′ if there is a path of length 2 between u and v in G. I understand the question very well and have found an algorithm which I assume is correct, however the runtime of my algorithm is O(VE^2) where V is the number of vertices and E is the number of Edges of the graph. I was wondering how I could do this in O(VE) time in order to make it more efficient?
Here is the algorithm, I came up with:
for vertex in Vertices
for neighbor in Neighbors
for n in Neighbors
if(n!=neighbor)
then-> if(n.value==neighbor)
add this to a new adjacency list
break; // this means we have found a path of size 2 between vertex and neighbor
continue otherwise
The problem can be solved in time O(VE) using BFS(breadth first search). The thing about BFS, is that it traverses the graph level by level. Meaning that first it traverses all the vertices at a distance of 1 from the source vertex. Then it traverses all the vertices at a distance of 2 from the source vertex and so on. So we can take advantage of this fact and terminate our BFS, when we have reached vertices at a distance of 2.
Following is the pseudocode:
For each vertex v in V
{
Do a BFS with v as source vertex
{
For all vertices u at distance of 2 from v
add u to adjacency list of v
and terminate BFS
}
}
Since BFS takes time O(V + E) and we invoke this for every vertex, so total time is O(V(V + E)) = O(V^2 + VE) = O(VE) .Just remember to start with fresh data structures for every BFS traversal.

How to update MST from the old MST if one edge is deleted

I am studying algorithms, and I have seen an exercise like this
I can overcome this problem with exponential time but. I don't know how to prove this linear time O(E+V)
I will appreciate any help.
Let G be the graph where the minimum spanning tree T is embedded; let A and B be the two trees remaining after (u,v) is removed from T.
Premise P: Select minimum weight edge (x,y) from G - (u,v) that reconnects A and B. Then T' = A + B + (x,y) is a MST of G - (u,v).
Proof of P: It's obvious that T' is a tree. Suppose it were not minimum. Then there would be a MST - call it M - of smaller weight. And either M contains (x,y), or it doesn't.
If M contains (x,y), then it must have the form A' + B' + (x,y) where A' and B' are minimum weight trees that span the same vertices as A and B. These can't have weight smaller than A and B, otherwise T would not have been an MST. So M is not smaller than T' after all, a contradiction; M can't exist.
If M does not contain (x,y), then there is some other path P from x to y in M. One or more edges of P pass from a vertex in A to another in B. Call such an edge c. Now, c has weight at least that of (x,y), else we would have picked it instead of (x,y) to form T'. Note P+(x,y) is a cycle. Consequently, M - c + (x,y) is also a spanning tree. If c were of greater weight than (x,y) then this new tree would have smaller weight than M. This contradicts the assumption that M is a MST. Again M can't exist.
Since in either case, M can't exist, T' must be a MST. QED
Algorithm
Traverse A and color all its vertices Red. Similarly label B's vertices Blue. Now traverse the edge list of G - (u,v) to find a minimum weight edge connecting a Red vertex with a Blue. The new MST is this edge plus A and B.
When you remove one of the edges then the MST breaks into two parts, lets call them a and b, so what you can do is iterate over all vertices from the part a and look for all adjacent edges, if any of the edges forms a link between the part a and part b you have found the new MST.
Pseudocode :
for(all vertices in part a){
u = current vertex;
for(all adjacent edges of u){
v = adjacent vertex of u for the current edge
if(u and v belong to different part of the MST) found new MST;
}
}
Complexity is O(V + E)
Note : You can keep a simple array to check if vertex is in part a of the MST or part b.
Also note that in order to get the O(V + E) complexity, you need to have an adjacency list representation of the graph.
Let's say you have graph G' after removing the edge. G' consists have two connected components.
Let each node in the graph have a componentID. Set the componentID for all the nodes based on which component they belong to. This can be done with a simple BFS for example on G'. This is an O(V) operation as G' only has V nodes and V-2 edges.
Once all the nodes have been flagged, iterate over all unused edges and find the one with the least weight that connects the two components (componentIDs of the two nodes will be different). This is an O(E) operation.
Thus the total runtime is O(V+E).

Resources