Algorithm 如何在线性时间内找到树中最短的简单路径?
这是Vazirani的算法书中的一个问题 这个问题的输入是一个边上有整数权重的树T。权重可能为负数, 零,或正。给出了求T中最短简单路径的线性时间算法 路径是路径中边的权重之和。如果没有重复顶点,则路径很简单。注 路径的端点不受约束 提示:这与在树中查找最大独立集的问题非常相似 如何在线性时间内解决这个问题 这是我的算法,但我想知道它是否是线性时间,因为它与深度优先没有什么不同:Algorithm 如何在线性时间内找到树中最短的简单路径?,algorithm,graph,graph-theory,dynamic-programming,graph-algorithm,Algorithm,Graph,Graph Theory,Dynamic Programming,Graph Algorithm,这是Vazirani的算法书中的一个问题 这个问题的输入是一个边上有整数权重的树T。权重可能为负数, 零,或正。给出了求T中最短简单路径的线性时间算法 路径是路径中边的权重之和。如果没有重复顶点,则路径很简单。注 路径的端点不受约束 提示:这与在树中查找最大独立集的问题非常相似 如何在线性时间内解决这个问题 这是我的算法,但我想知道它是否是线性时间,因为它与深度优先没有什么不同: 遍历树(深度优先) 保留索引(节点) 添加值 直到树的尽头 比较总和并打印路径和总和 这个问题与此类似,但没有确定的
这个问题与此类似,但没有确定的答案。这个问题几乎等同于,可以通过动态规划以类似的方式解决 我们将使用DF搜索计算以下数组:
dw1[i] = minimum sum achievable by only using node i and its descendants.
pw1[i] = predecessor of node i in the path found for dw1[i].
dw2[i] = second minimum sum achevable by only using node i and its descendants,
a path that is edge-disjoint relative to the path found for dw1[i].
如果可以计算这些值,则取min(dw1[k],dw1[k]+dw2[k])
所有k
。这是因为您的路径将采用以下基本形状之一:
k k
| or / \
| / \
|
所有这些都包含在我们的金额中
计算dw1
从根节点运行DFS。在DFS中,跟踪当前节点及其父节点。在每个节点上,假设其子节点是d1、d2、。。。dk
。然后dw1[i]=min(min{dw1[d1]+成本[i,d1],dw1[d2]+成本[i,d2],…,dw1[dk]+成本[i,dk]},min{cost[i,dk]}
。为叶节点设置dw1[i]=0
。不要忘记用所选的前置程序更新pw1[i]
计算dw2
从根节点运行DFS。对dw1
执行相同的操作,除了从节点i
转到其子节点k
时,如果pw1[i]!=k
。但是,您可以为所有子级递归调用该函数。它在伪代码中看起来像这样:
df(node, father)
dw2[node] = inf
for all children k of node
df(k, node)
if pw1[node] != k
dw2[node] = min(dw2[node], dw1[k] + cost[node, k], cost[node, k])
瓦齐拉尼近似书?我不明白这个问题,树上的每一条边都是路径,最小的边都是最短路径,你们能用这个来澄清我吗,或者用谷歌搜索一下问题的确切名称吗?你是说寻找最短路径树吗?或者树根?@Saeed-最小的边不一定是最短的路径,因为你可以有负的权重。那么空路径呢?它是最短的,不是吗?对于路径应该包含什么,您没有提出任何要求。这没有意义。@Tomas的空路径的权重为零。由一条负权重边组成的路径更短。提示说,这个问题与在树中找到最大的独立集有关。对这意味着什么有什么想法吗?看起来很有希望,但我有一些建议:(1)在“计算dw1”下,当你说“后代”时,我相信你指的是“孩子”(“后代”通常递归地指所有孩子和孩子的孩子);(2)
dw1[i]
、dw2[i]
和up[i]
的计算应在min{…}
操作中包含0,以允许路径终止于此(例如,不包含负长度边的树将返回0分);(3) 我相信您对dw2[I]的计算应该排除最佳前沿。。。。。。仅从顶点i
,但较低级别应包括最佳边(询问是否需要澄清);(4) up[i]
计算可以通过注意每个路径都有两种类型中的一种来简化:要么是“直下”路径,要么是包含“最上角”(顶点v使v的父节点不在路径中)——通过考虑dw1[v]+dw2[v]
,可以找到在某些顶点v包含最上角的任何路径,因此,up[i]
只需计算返回根目录的直线路径上的成本(即,up[i]
将是以i
结尾的“直线路径”的最低成本)。@j_random\u hacker-我刚刚意识到,当你写下评论并将其删除时:)。是否需要将dw2[k]
置于最低限度?它永远不会小于dw1[k]
。不久前,我解决了一个问题,它会询问诸如包含q的最短路径是什么?
,因此我开始使用up
。但要知道这里不需要它。@becko:恐怕我看不出有什么联系。。。我知道树中的独立集可以用一种大致相似的方法求解,方法是为每个具有DFS的节点计算2个值:在使用节点I的以节点I为根的子树中最大独立集的大小,以及在不使用节点I的以节点I为根的子树中最大独立集的大小。分别称之为x(i)和y(i)。然后你可以通过为i的每个子j取1+和(y(j))来计算x(i),也可以通过为i的每个子j取和(x(j))来计算y(i)。@becko:刚刚注意到一个错误!对于i的每个子j,y(i)应该是总和(max(x(j),y(j)),因为我们只想允许,而不是要求子元素包含在独立集中。