我有一个树和3个节点A
,B
,C
。问题是找到A
和B
的路径大小将分享他们通往C
的最短路径。
有3例:
当C
是A
和B
的祖先时。在这种情况下,答案是min(depth(A), depth(B)) - depth(C)
当C
是A
的祖先但不是B
或者是副的时候。在这种情况下,答案是1
,只是节点C
我无法确定A
和B
都不是C
的后代。
我会有很多疑问,所以我需要一种有效的方法。如果我们无法在O(logN)
中获得每个LCA,则每个查询都应为O(1)
。
答案 0 :(得分:2)
作为上述答案中的DAle pointed out,一种方法可以基于他讲述的方式,即将树的根作为C
,然后检查路径。
另一种方法可以是以类似的方式找到A和B的最低公共后代(LCD)。总之,我们可以找到第一个节点,其中A和A的路径都是B会在走向 C时与相交,然后将该节点的路径大小赋予C.然后可能会出现这种情况:
答案 1 :(得分:0)
树修改算法
我能想到的最简单的算法可能需要根据源代码的初始表示来修改源代码树。
C
作为树的根。所以我们需要改变树中的父子关系。 找到A
和B
的{{3}}。 LCA是最大深度的节点,它是A
和B
(以及LCA(A, A) = A
)的祖先。
答案是depth(LCA(A,B))
。
没有树修改的算法
如果我们无法转换树,那么:
如果C
是A
和B
的祖先,则答案为depth(LCA(A, B)) - depth(C) + 1
。 (你在这个问题上有错误。)
lowest common ancestor (LCA)
depth(C) -
max(depth(A), depth(B)) + 1
不是C
和A
的祖先或后代,则答案将是B
和顶点C
之间的距离,该距离等于{ {1}}。 更新:现在问题中出现了每个操作要求D = LCA(A, B)
。我认为,只有保证depth(C) + depth(D) - 2*depth(LCA(C, D)) + 1
时间复杂度,才能预先计算所有O(1)
。例如,可以使用来完成此操作。