简体   繁体   English

最小的生成树以最小化成本

[英]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. 我们有一组E道路,一组H公路和一组V不同的城市。 We also have a cost x(i) associated to each road i and a cost y(i) associated to each highways i. 我们还有与每条道路i相关的成本x(i)和与每条公路i相关的成本y(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. 集合E和集合H不同,并且它们各自的成本无关。

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. 比较第2步的成本和最小的成本(如果较小的话)。
  4. remove that high way. 删除高方式。
  5. go back to step 2 and go the steps again for each highway. 返回第2步,然后针对每个高速公路再次执行该步骤。

O(nm) = m*mst_cost(n) O(纳米)= m * mst_cost(n)

Using Prim's or Kruskal's to build an MST: O(E log V) . 使用Prim或Kruskal来构建MST: O(E log V)

The problem is the constraint of at most 1 highway. 问题是最多只能有1条高速公路。

1. Naive method to solve this: 1.天真的方法来解决这个问题:

For each possible highway, build the MST from scratch. 对于每个可能的高速公路,从头开始构建MST。

Time complexity of this solution: O(HE log V) 该解决方案的时间复杂度: O(HE log V)

2. Alternative 2.替代

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. 想法:如果您构建了一个MST,并且您有一个以前从未考虑过的可用边缘,则可以使用更好的MST来优化MST。

Suppose the new edge connects (u,v) . 假设新边连接(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. 如果使用此边缘,则可以删除MST中顶点uv之间路径中最昂贵的边缘。 You can find the path naively in O(V) time. 您可以在O(V)时间中天真地找到路径。

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. 使用此想法,时间复杂度是建立初始MST O(E log V)的成本,以及尝试使用每条H高速公路细化MST的时间。 The total algorithmic complexity is therefore O(E log V + HV) , which is better than the first solution. 因此,总算法复杂度为O(E log V + HV) ,这比第一个解决方案要好。

3. Optimized refinement 3.优化细化

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). 一个相关的问题是LCA(最低共同祖先)。 A good way of solving LCA is using jump pointers. 解决LCA的一个好方法是使用跳转指针。 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). 首先,您要树根,然后每个顶点将具有指向根的跳转指针(1步,2步,4步等)。预处理可能会花费O(V log V)时间,而找到2个顶点的LCA为O(log V)最坏的情况(尽管实际上是O(log (depth of tree))通常更好)。

Once you have found the LCA, that implicitly gives you the path between vertices u and v . 一旦找到LCA,就会隐式地为您提供顶点uv之间的路径。 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. 在一维问题中,可以采用范围最大查询(RMQ)。 This uses a segment tree to solve the RMQ in O(log N) time. 这使用段树来解决O(log N)时间中的RMQ。

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. 为了找到LCA,树中的每个顶点将具有指向根的log(tree depth)跳转指针。 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. 因此,对LCA算法的略微改进使我们能够在O(log (depth))时间上找到顶点uv之间的路径上的最大边缘权重。

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) . 最后,综合起来,该第三种解决方案的算法复杂度为O(E log V + H log V)或等效地O((E+H) log V)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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