Here is an excise
Suppose we are given the minimum spanning tree T of a given graph G
(with n vertices and m edges) and a new edge e = (u, v) of weight w
that we will add to G. Give an efficient algorithm to find the minimum
spanning tree of the graph G + e. Your algorithm should run in O(n)
time to receive full credit.
I have this idea:
In the MST, just find out the path between u and v. Then find the edge (along the path) with maximum weight; if the maximum weight is bigger than w, then remove that edge from the MST and add the new edge to the MST.
The tricky part is how to do this in O(n) time and it is also I get stuck.
The question is that how the MST is stored. In normal Prim’s algorithm, the MST is stored as a parent array, i.e., each element is the parent of the according vertex.
So suppose the excise give me a parent array indicating the MST, how can I release the above algorithm in O(n)?
First, how can I identify the path between u and v from the parent array? I can have two ancestor arrays for u and v, then check on the common ancestor, then I can get the path, although in backwards. I think for this part, to find the common ancestor, at least I have to do it in O(n^2), right?
Then, we have the path. But we still need to find the weight of each edge along the path. Since I suppose the graph will use adjacency-list for Prim’s algorithm, we have to do O(m) (m is the number of edges) to locate each weight of the edge.
…
So I don’t see it is possible to do the algorithm in O(n). Am I wrong?
The idea you have is right. Note that, finding the path between
uandvisO(n). I’ll assume you have aparent arrayidentifying the MST. tracking the path (for max edge) fromutovorutoroot vertexshould take onlyO(n). If you reachroot vertex, just track the path fromvtouorroot vertex.Now that you have the path from
u -> u1 ... -> max_path_vert1 -> max_path_vert2 -> ... -> v, remove the edgemax_path_vert1->max_path_vert2(assuming this is greater than the added edge) and reverse the parents foru->...->max_path_vert1and markparent[u] = v.Edit: More explanation for clarity
Note that, in MST there will be exactly one path between any pair of vertices. So, if you can trace from
u->yandv->y, you have only traced through atmostnvertices. If you traced more thannvertices that means you visited a vertex twice, which will not happen in an MST. Ok, now hopefully you’re convinced it’s O(n) to track fromu->yandv->y. Once you have these paths, you have established a path fromu->v. Do you see how? I’m assuming this is an undirected graph, since finding MST for directed graph is a different concept in itself. For undirected graph, when you have a path fromx->yyou have a path fromy-x. So,u->y->vexist. You don’t even need to trace back fromy->v, since weights forv->ywill be same as that ofy->v. Just find the edge with the maximum weight when you trace fromu->yandv->y.Now for finding edge weights in O(1); how are you storing your current weights? Adjacency list or adjacency matrix? For O(1) access, store it the way parent vertex array is stored. So,
weight[v] = weight(v, parent[v]). So, you’ll have O(1) access. Hope this helps.