[英]In tree check if given node is ancestor of another
我有一个问题-如果给定2个节点(A,B)是B的祖先,我需要回答这个问题。我知道可能的解决方案是获取进入节点的时间和离开节点的时间。 基于此,我可以快速计算关系。 如何使用DFS获得那些无法通过重复实现的“时间戳”?
我不是算法和C ++方面的专家,这就是为什么我要问。
使用标准的增强线程索引(ATI-请参见下面提供的参考),该索引提供了节点长度数据结构(通常是数组),无法在恒定时间内回答A
是否是B
的祖先的问题。
如果存储每个节点的pred
, thread
和depth
(构成ATI方案中的基本数据结构),则可以在O(N)
时间内完成A
是否是B
的祖先的问题-只需从B
回溯即可使用pred
数据结构,直到到达root
并检查是否遇到A
但是,您可以对每个节点执行上述操作作为预处理步骤,然后拥有一个新的节点长度数组,即每个节点的ancestor
,它指示另一个节点是否是其祖先。
参考: Bazaara,Jarvis和Sherali第482页。
我找到了一种方法。 如果您的树在邻接列表中,那么您可以进行预处理。 对于每个节点,您需要在输入值时以及在DFS中离开值时分配值,然后可以在固定时间内检查它:
if (timeIn[b] >= timeIn[a] && timeIn[b] <= timeOut[a]) {
printf("YES\n");
}
else {
printf("NO\n");
}
如果a是b的祖先。
DFS:
// INITIALIZE VARs
int time = 0;
stack<int> stackOfChildNodes;
// put root of tree
stackOfChildNodes.push(first);
// go with DFS
while (!stackOfChildNodes.empty()) {
int current = stackOfChildNodes.top();
stackOfChildNodes.pop();
// if node was not visited (time is not set)
if (timeIn[current] == -1) {
timeIn[current] = time; // node visited
time++; // increase time to go further
stackOfChildNodes.push(current); // include node in processing to leave it in future
int child = children[current];
// add descendants to process them
while (child != 0) {
stackOfChildNodes.push(child);
child = descendants[child];
}
}
// if node was visited, so we gonna leave him now
if (timeIn[current] != -1) {
timeOut[current] = time-1;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.