这是一个消费税
假设给出了给定图G的最小生成树T. (具有n个顶点和m个边)和权重w的新边e =(u,v) 我们将添加到G.给出一个有效的算法来找到最小值 图G + e的生成树。 您的算法应该在O(n)中运行 是时候获得全额学分。
我有这个想法:
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.
棘手的部分是如何在O(n)时间内完成此操作,而且我也被卡住了。
问题是如何存储MST。在普通的Prim算法中,MST存储为父数组,即每个元素都是相应顶点的父元素。
所以假设消费税给了我一个表明MST的父数组,我怎样才能在O(n)中释放上述算法?
首先,如何从父数组中识别u和v之间的路径?我可以为你和你有两个祖先数组,然后检查共同的祖先,然后我可以得到路径,虽然在后面。我认为对于这一部分,找到共同的祖先,至少我必须在O(n ^ 2)中做,对吧?
然后,我们有了路径。但是我们仍然需要找到路径上每条边的重量。由于我认为图形将使用邻接列表用于Prim算法,我们必须做O(m)(m是边数)来定位边缘的每个权重。
...
所以我认为不可能在O(n)中进行算法。我错了吗?
答案 0 :(得分:1)
你的想法是正确的。请注意,查找u
和v
之间的路径为O(n)
。我假设你有一个parent array
来识别MST。跟踪从u
到v
或u
到root vertex
的路径(最大边缘)应该只需O(n)
。如果您到达root vertex
,只需跟踪从v
到u
或root vertex
的路径。
现在您拥有u -> u1 ... -> max_path_vert1 -> max_path_vert2 -> ... -> v
的路径,删除边max_path_vert1->max_path_vert2
(假设这大于添加的边缘)并反转u->...->max_path_vert1
的父级并标记{{1} }。
编辑:更清晰的解释
请注意,在MST中,任何一对顶点之间只有一条路径。因此,如果您可以追踪parent[u] = v
和u->y
,那么您只能追踪最近的v->y
个顶点。如果跟踪的n
个顶点超过n
,则意味着您访问了两次顶点,这在MST中不会发生。好的,现在希望您确信从u->y
和v->y
跟踪是O(n)。获得这些路径后,您已经建立了u->v
的路径。你看到了吗?我假设这是一个无向图,因为找到有向图的MST本身就是一个不同的概念。对于无向图,当您有x->y
的路径时,您有y-x
的路径。所以,u->y->v
存在。您甚至无需追溯y->v
,因为v->y
的权重与y->v
的权重相同。从u->y
和v->y
跟踪时,只需找到具有最大权重的边缘。
现在在O(1)中找到边权重;你如何存储当前的重量?邻接列表或邻接矩阵?对于O(1)访问,以父顶点数组的存储方式存储它。所以,weight[v] = weight(v, parent[v])
。所以,你将有O(1)访问权限。希望这会有所帮助。
答案 1 :(得分:0)
嗯 - 你的解决方案是正确的。
但是关于实现,我不明白为什么你使用G而不是T来找到u和v之间的路径。在T中使用任何搜索遍历u和v之间的路径,将给你O(n)。 - 也就是说,您可以假设v是根并且执行深度优先搜索算法[在这种情况下,您将必须假设v的所有邻居作为子项] - 并且一旦找到您就停止DFS - 然后,堆栈中的节点对应于u和v之间的路径。
之后很容易找到路径中每条边的成本(O(n)),并且删除/添加边也很容易。总共O(n)。
这会有所帮助吗?
或许你得到O(n ^ 2) - 根据我的理解 - 因为你在O(n)中的T中访问顶点v的子节点 - 在这里,你必须将你的数据结构呈现为映射数组使成本降低到O(1)。 [对于instace,{a,b,c,u,w}(顶点) - > {0,1,2,3,4}(顶点索引)。