Find a MST in O(V+E) Time in a Graph

3.4k Views Asked by At

Similar question has been asked before, as in https://cs.stackexchange.com/questions/28635/find-an-mst-in-a-graph-with-edge-weights-from-1-2

The question is: Given a connected undirected graph G=(V,E) and a weight function w:E→{1,2}, suggest an efficient algorithm that finds an MST of the graph in O(V+E) without using Kruskal.

I had a look at the suggested solutions on the thread above, but am still not sure how to make it work. The first suggestion doesn't consider components. The second suggestion doesn't provide more details on how to identify if the newly considered edge will form a cycle if it is added to the current MST. The tricky part is how to identify if two vertices are in the same component in liner time.

My current thought is

  1. sort the vertices, which can be done in linear time
  2. consider edges with weight 1 first. add the edge to the MST when the number of edges is less than or equal to |V1|-1. V1 are the vertices on the edges with a weight of 1. We need to make sure all the vertices with a weight of 1 is checked. Hash set can be used to store V1 and edges.
  3. add V2 to the graph by using the same logic.

Could anyone suggest if my thought has flaws? If so, what is the best way to tackle this question? Thank you very much!

1

There are 1 best solutions below

1
On BEST ANSWER

I would suggest you to do something like the second answer in the given question:

This is prim's algorithm :

Start by picking any vertex to be the root of the tree.

While the tree does not contain all vertices in the graph find shortest edge leaving the tree and add it to the tree .

So now if we can perform the finding in the set of edges leaving the tree in O(1) time and we can keep the set updated so the search can always happen in constant time in total O(|E|) time, then we are good to go.

Now for this to happen, think of the set of edges leaving the tree as a linked list. now whenever a vertex is added to the set of vertexes that form the MST, iterate through its adjacency list and add the edges of weight 1 to the front of the list, and add the edges of weight 2 to the end of the list. Now whenever you want the minimum edge leaving the tree just take one from the front of the linked list!

The only problem with this method is that you should only add the edges to the list that are "leaving the tree"! because if we don't, we might end up having cycles! For checking this "leaving the tree" property for each edge, we can use the set of selected vertices, and we can check each edge before adding, that it doesn't have both ends in the set, so simply when you are adding the edges of a newly added vertex to set of edges leaving the tree, first check if the vertex on the other end of the edge is in the set of selected vertices of tree, and add the edge to the list only if the other edge wasn't in the set. You can check existence of an element in a set in O(1) time and this way you won't end up with cycles!