给定每个节点的树和值,我们如何获得每个可能路径的总和?
A
|
B
在上面的树中将有4条这样的路径:A,B,A-B,B-A。
每个节点都会分配一个值:A: 3, B: 2
预期输出应为:3 + 2 +(3 + 2)+(2 + 3)
这个问题的一个天真的解决方案是从源到目标(对于每个可能的组合)进行DFS并通过添加DFS结果来获得总和,但我相信这个问题可以通过DP更有效地解决,但是不要真的有很多DP经验。
答案 0 :(得分:1)
这个有一个很好的解决方案,它不涉及(很多)动态编程:
您可以计算每个节点在路径中出现的频率。让我们以n=5
个节点为例:
A
|
B
/ \
C D
|
E
叶子A
,C
和E
的计算非常简单。它们仅出现在以此节点开头或结尾的路径中。有2n - 1 = 9
个路径-1
,因为路径A
的开头和结尾都是A
,因此会在2*n
中计算两次。
对于内部节点,它变得有点棘手。让我们先看看节点D
。当然D
出现在所有路径中,以D
开头或结尾。所以我们再次拥有2n - 1 = 9
个路径。但现在也可能是D
出现在路径中间的某个地方。例如。在路径A-B-D-E
中。只有当路径从子树ABC
中的某个位置开始并以子树E
或相反的方式结束时,才会发生这种情况。 Combinatorics告诉我们,有size(ABC)*size(E) + size(E)*size(ABC) = 2*size(ABC)*size(E) = 2*3*1 = 6
多个。因此,D
恰好出现在9 + 6 = 15
个路径中。
对于节点B
,它仍然有点棘手。从2n - 1 = 9
开始或结束的路径再次出现B
(每个节点都是如此)。但是B
再次出现在路径中间的某个地方。要实现此目的,路径必须从其中一个子树A
,C
或DE
开始,并以不同的方式结束。所以有2*size(A)*size(C) + 2*size(C)*size(DE) + 2*size(DE)*size(A) = 2*1*1 + 2*1*2 + 2*2*1 = 2 + 4 + 4 = 10
个可能的路径。通过一些数学运算,您可以看到这与(n-1)^2 - size(A)^2 - size(C)^2 - size(DE)^2
相同。因此,总共节点出现在9 + 10 = 19
路径中。
您要计算的值为9*value(A) + 19*value(B) + 9*value(C) + 15*value(D) + 9*value(E)
。
通过一次深度优先搜索,您可以使用动态编程计算所有子树的大小,并使用这两个公式计算每个节点的出现次数。