树中心节点(距离感最小值)

时间:2016-11-23 14:33:50

标签: algorithm graph-theory

我的问题如下:

给定树(V,E),找到中心节点v使得总和{w in V} [dist(v,w)]最小,其中dist(v,w)是最短的边数从v到w的路径。算法应该在O(n)时间内运行(n是树中节点的数量)。

问题herehere也要求中心节点,但以不同方式定义。

我没有经过严格的步骤,但实际上我认为我的问题的解决方案应该类似于this problem的解决方案。

但是,我决定与社区分享我的问题,因为我花了一段时间导航到the link,然而却没有直接回答这个问题。

2 个答案:

答案 0 :(得分:2)

我提出了这个解决方案:

1)选择任意节点作为根r,形成树。对于此树中的每个子树,计算子树中的节点数(叶子是单节点树)。

作为这棵树的一个例​​子

          1
        / | \
       2  3  4 
      / \     \
     5   6     7
        / \
       8   9      

结果将是

          9
        / | \
       5  1  2 
      / \     \
     1   3     1
        / \
       1   1    

2)计算此选定根的距离总和。例如,如果选择顶点1作为根,则距离之和为 0 + 1 + 1 + 1 + 2 + 2 + 2 + 3 + 3 = 15

3)以depth-first-search方式遍历树。例如,从顶点1开始,我们遍历顶点4.我们观察到7个节点(1,2,3,5,6,8,9),我们进一步增加1(添加7 = 9-2到得分),对于其他2(4,7),我们越来越接近1(减去2)。这使得距离总和等于15 +(9-2)-2 = 20.

假设我们接下来从4到7遍历。现在我们得到的距离总和等于20+(9-1)-1 = 27(从8个顶点进一步增加,并且越来越接近1个顶点)。

作为另一个例子,如果我们从1遍历到2,我们得到的距离之和等于15+(9-5)-5 = 14.顶点2实际上就是这个例子的解。

这将是我的算法。

答案 1 :(得分:0)

每条边e = {a,b}具有以下属性:

  • a_count =一侧的节点数(包括a)
  • b_count = b侧的节点数(包括b)
  • a_sum =从a到其子树节点的距离之和
  • b_sum =从b到其子树节点的距离之和

节点e = {a,b}的a_count可以评估如下: *得到a的所有边缘,不包括e,求和a_count *在总和上加1

节点e = {a,b}的a_sum可以评估如下: *得到a的所有边缘,不包括e,总和他们的a_sum *添加a_count(每个枚举边包含+1,a包含+1)

您可以在接受节点和方向参数的递归函数中自由地进行计算,将获得的结果保存在全局数组中。

如果在两个方向上在树的每个边缘上运行此功能,则可以完全计算边缘。所有计算的总时间是O(n),因为一旦你得到一些子树,递归性质将在这个方向上关闭整个子树,下一次调用将从全局数组中获得结果,并且你只为你的函数做2 * n次调用。

对于节点最终度量是连接到节点的所有边的所有B_count + B_sum的总和。在节点上执行此评估的一次运行,并选择具有最小值的节点。