这是我正在努力的练习考试中的一个问题:
设G =(V,E)为加权无向连通图,为正 权重(您可以假设权重不同)。鉴于真实 数字r,定义子图Gr =(V,{E in E | w(e)< = r})。对于 例如,G0没有边缘(明显断开连接),Ginfinity = G. (通过假设连接)。问题是要找到 最小的r使得Gr连接起来。
描述一个解决问题的O(mlogn)时间算法 重复申请BFS或DFS。
真正的问题是在O(mlogn)中进行。这就是我所拥有的:
r = min( w(e) ) => O(m)
while true do => O(m)
Gr = G with edges e | w(e) > r removed => O(m)
if | BFS( Gr ).V | < |V| => O(m + n)
r++ (or r = next smallest w(e))
else
return r
这是一个惊人的O(m ^ 2 + mn)。任何将它降到O(mlogn)的想法?谢谢!
答案 0 :(得分:3)
以下算法怎么样?
首先从图中获取所有边(或所有不同边长,使用)的列表并对它们进行排序。这需要O(m * log m)= O(m * log n)时间:m通常小于n ^ 2,因此O(log m)= O(log n ^ 2)= O(2 * log n) = O(log n)。
很明显,r应该等于某些边缘的重量。因此,您可以对已排序数组中的边的索引进行二进制搜索。
对于您尝试的每个索引,将对应边的长度设为r,并检查图的连通性,仅使用长度&lt; = r与BFS或DFS的边。
二进制搜索的每次迭代都需要O(m),你必须进行O(log m)= O(log n)次迭代。
答案 1 :(得分:3)
您正在迭代所有可能的边缘成本,这导致外部循环为O(m)。请注意,如果在丢弃所有边&gt; w(e)时断开图形,则对于&gt; w(e')w(e') < w(e)
也会断开连接。您可以使用此属性对边成本进行二进制搜索,从而在O(log(n))中执行此操作。
lo=min(w(e) for e in edges), hi=max(w(e) for e in edges)
while lo<hi:
mid=(lo+hi)/2
if connected(graph after discarding all e where w(e)>w(mid)):
lo=mid
else:
hi=mid-1
return lo
二进制搜索的复杂度为O(log(max_e-min_e))(实际上可以将其降低到O(log(边缘))并丢弃边缘并确定连接可以在O(边缘+顶点)中完成,所以这可以在O((edge + vertices)* log(edges))中完成。
警告:我还没有在代码中对此进行测试,因此可能存在错误。但这个想法应该有效。