简体   繁体   中英

Minimum spanning tree to minimize cost

Can someone please help me solve this problem?

We have a set E of roads, a set H of highways, and a set V of different cities. We also have a cost x(i) associated to each road i and a cost y(i) associated to each highways i. We want to build the roads to connect the cities, with the conditions that there is always a path between any pair of cities and that we can build at most one highway, which may be cheaper than a road.

Set E and set H are different, and their respective costs are unrelated.

Design an algorithm to build the roads (with at most one highway) that minimize the total cost.

So, what we have is a fully connected graph of edges.

Solution steps:

  1. Find the minimum spanning tree for the roads alone and consider it as the minimum cost.
  2. Add one highway to the roads graph an calculate the minimum spanning cost tree again.
  3. compare step 2 cost with the minimum cost to replace it if its smaller.
  4. remove that high way.
  5. go back to step 2 and go the steps again for each highway.

O(nm) = m*mst_cost(n)

Using Prim's or Kruskal's to build an MST: O(E log V) .

The problem is the constraint of at most 1 highway.

1. Naive method to solve this:

For each possible highway, build the MST from scratch.

Time complexity of this solution: O(HE log V)

2. Alternative

Idea: If you build an MST, you can refine the MST with a better MST if you have an additional available edge you have not considered before.

Suppose the new edge connects (u,v) . If you use this edge, you can remove the most expensive edge in the path between vertices u and v in the MST. You can find the path naively in O(V) time.

Using this idea, the time complexity is the cost to build the initial MST O(E log V) and the time to try to refine the MST with each of the H highways. The total algorithmic complexity is therefore O(E log V + HV) , which is better than the first solution.

3. Optimized refinement

Instead of doing a naive path-searching method with the second method, we can find a faster way to do this. One related problem is LCA (lowest-common ancestor). A good way of solving LCA is using jump pointers. First you root hte tree, then each vertex will have jump pointers towards the root (1 step, 2 steps, 4 steps etc.) Pre-processing might cost O(V log V) time, and finding the LCA of 2 vertices is O(log V) worst case (although it is actually O(log (depth of tree)) which is usually better).

Once you have found the LCA, that implicitly gives you the path between vertices u and v . However, to find the most expensive edge to delete could be expensive since traversing the path is costly.

In 1-dimensional problems, the range-maximum-query (RMQ) can be employed. This uses a segment tree to solve the RMQ in O(log N) time.

Instead of a 1-dimensional space (like an array), we have a tree. However, we can apply the same idea, and build a segment tree-like structure. In fact, this is equivalent to bundling an extra piece of information with each jump pointer. To find the LCA, each vertex in the tree will have log(tree depth) jump pointers towards the root. We can bundle the maximum edge weight of the edges we jump over with the jump pointer. The cost of adding this information is the same as creating the jump pointer in the first place. Therefore, a slight refinement to the LCA algorithm allows us to find the maximum edge weight on the path between vertices u and v in O(log (depth)) time.

Finally, putting it together, the algorithmic complexity of this 3rd solution is O(E log V + H log V) or equivalently O((E+H) log V) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM