这是问题,我的尝试解决方案。
我的解决方案: 1.在树上运行拓扑排序,它以线性时间BigTheta(E + V)运行,其中E是边数,V是顶点数。这将它放在一个链表中,也需要一段时间。 2.如果顶点u的顶点时间比顶点v高,则顶点u将是祖先。 3.查看链表中的2个顶点并比较它们的结束时间,并根据步骤2的结果返回true或false。
这听起来不错还是我错过了什么?
答案 0 :(得分:0)
我不认为你对“恒定时间”意味着什么的理解是完全正确的。 “...时间BigTheta(E + V)其中E是边数,V是顶点数”是线性时间,而不是常数时间。
当然,你可以花时间进行预处理,所以没关系,但是你怎么在恒定的时间内完成你的第3步(“查看链表中的2个顶点”)? / p>
答案 1 :(得分:0)
这是一种适用于任何树(不仅仅是二进制)的方法。预处理步骤是执行树的Euler Tour(这只是一个DFS遍历)并创建一个列表。当您第一次访问节点时,将其附加到列表中以及上次将其附加到列表时访问它时。
示例:
x
/ \
y z
列表如下:[b(x), b(y), e(y), b(z), e(z), e(x)]
。此处b(x)
表示输入x
,e(x)
表示请离开x
。现在,您拥有此列表后,可以通过在列表中执行测试is x an ancestor of y
来回答查询b(x) is before b(y) and e(y) is before e(x)
。
问题是如何在恒定的时间内完成这项工作?
对于静态树(您就是这种情况),您可以使用查找表(也称为数组)来存储b/e
,现在测试需要持续时间。所以这解决了你的问题。