给出无向图G =(V,E)。首先询问MST的成本是多少。 我可以很容易地找到使用Kruskall算法,如下所示:
G = (V, E)
for each edge (u, v) in E sorted by wight
{
if(Find(u) != Find(v))
{
Add (u, v) to the MST
Union(u, v); // put u and v in the same set
}
}
之后,对于初始图中的每个边,询问最小生成树中该边的新MST的成本应该是多少。
如果MST中已存在边缘,则答案保持不变。否则,我可以再次运行Kruskall。伪代码如下:
G = (V, E)
G1 = runKruskall(G)
for each edge (u, v) in E
{
ClearUnionSets()
if (u, v) in G1
{
print costOf(G1)
} else {
Union(u, v)
G2 = runKruskall(G)
print costOf(G2)
}
}
该方法的问题在于总复杂度为:O(E * E)
我的问题是,如果有更好的解决方案来更新MST,如上所述。
我在想的是,当第一次运行Kruskall时,对于每个边缘(u,v),u和v都在同一个集合中,找到已经存在于部分MST中的最大加权边缘具有(u,v)的循环并将该信息存储在M [u] [v]的矩阵M中。这样做,当边缘成为强制性时更新MST的问题将在O(1)中解决。
任何人都可以帮我吗?
答案 0 :(得分:1)
对于不在MST上的每个边缘u-v,包括边缘的最小生成树是u-v替换MST上从u到v的路径上的最大边缘的那个。
可以如下有效地找到要更换的边缘。首先,将MST置于任意顶点。我们将修改算法以找到两个顶点的lowest common ancestor(LCA),描述为here。除了为每个顶点存储第2个父节点之外,我们还将存储到第2个父节点的路径上的最大边缘。使用这个数组,当我们计算LCA时,我们还将计算到LCA路径上的最大边缘,这使我们在两个顶点之间的路径上获得最大边缘。
预处理包括在O(E log E)中找到MST并在O(N log N)中构建LCA的父表,需要O(N log N)空间。在此之后,找到每个边缘的修改的MST仅需要对LCA进行一次评估,这可以在O(log N)中执行。因此,总复杂度仅为O(E log E)。