识别节点位于另外两个节点之间

时间:2014-06-21 10:51:46

标签: algorithm

给出了树。边缘信息以邻接列表格式给出。

节点编号分别为1,2,3 ...... N。

树的根总是1。

现在,给出了两个指数。问题是上述两个索引的关键在于从根(1)到其他索引的方式。

约束

  1. 节点数量为10 ^ 5。
  2. 可以触发的最大查询数,10 ^ 5。
  3. 父ID始终小于子。
  4. 示例: -

    边缘: -

    1 2
    2 5
    1 3
    3 7
    1 4
    4 8
    8 9
    

    问题 -

    2 3  ( Answer - Not possible, from 1 to 2, 3 never comes in between and from 1 to 3, 2 never comes in between.)
    8 9  ( Answer - Possible, 8 lies in between 1 and 9)
    

    下一个例子: -

    1 2
    2 4
    2 5
    1 3
    3 6
    3 7
    3 8
    

3 个答案:

答案 0 :(得分:1)

假设父节点的ID(靠近根节点的ID)总是大于子节点的ID,就像你的例子中的情况一样,你可以从任何边缘轻松看到它是否引向根或远离它。因此基本算法将是:

given nodes n and m
find edge (x, n) or (n, x) such that x < n
repeat with node x until x is m or x is root

我不认为有更快的方法来确定一个节点是否在&#39;之间?根和另一个。当然,您可以通过使用适当的数据结构来提高性能,例如首先将每个节点映射到哈希集中的父节点。这是Python中的一个例子:

ROOT = 1
edges = ((1, 2), (2, 4), (2, 5), (1, 3), (3, 6), (3, 7), (3, 8))

parents = {}
for edge in edges:
    parent, child = min(edge), max(edge)
    parents[child] = parent

def is_anchestor_of(p, c):
    while c > p:
        if parents[c] == p:
            return True
        c = parents[c]
    return False

创建哈希映射的时间和空间复杂度在节点或边的数量上是O(n)(在树中几乎相同),is_anchestor_of的平均大小写复杂度是O(logn),但在最坏的情况下(非常不平衡的树或链)会恶化为O(n)。

您可以通过将每个节点映射到其所有的安慰者来提高查找复杂性。创建这个哈希映射的复杂性将是O(n log n),除非我误解了时间和空间,但在最坏的情况下可能会达到O(n ^ 2)。在任何情况下,使用这种结构,is_anchestor_of的复杂性是O(1),因为它只是在哈希映射中查找,然后在哈希集中查找。

anchestors = {}
for node in parents:
    anchestors[node] = set([ ROOT ])
    p = parents[node]
    while p != ROOT:
        anchestors[node].add(p)
        p = parents[p]

def is_anchestor_of(p, c):
    return p in anchestors[c]

在这两种情况下,只需检查一个人是否是另一个的安慰者。

def on_one_path(x, y):
    return is_anchestor_of(x, y) if x < y else is_anchestor_of(y, x)
print on_one_path(3, 8)

更新:似乎有一种更有效的方法;请参阅 @ Loha的答案。

答案 1 :(得分:1)

算法如下: -

  1. 从root开始,并为每个节点记下 IN TIME OUT TIME 。如你所说,给出了邻接表。您可以使用时间复杂度 O(节点总数)中的 DFS 轻松完成。
  2. 一个节点&#34; B&#34;是其他节点的后代&#34; A&#34;,只在一种情况下。

    IN_TIME(A)&lt; IN_TIME(B)和OUT_TIME(B)&lt; Out_time的(A)

  3. 这样,Query将处理 O(1)时间。

答案 2 :(得分:0)

对于每个节点,在树中构建其上方节点的排序列表:

1 {}
2 {1}
3 {1}
4 {1}
5 {1, 2}
7 {1, 3}
8 {1, 4}
9 {1, 4, 8}

然后,当给出查询时,搜索列表中属于另一个的每个节点( O(logN)):

2 3: 2 is not in {1}, and 3 is not in {1}, so the answer is no.
8 9: 9 is not in {1, 4}, but 8 is in {1, 4, 8}, so the answer is yes.

修改

正如tobias_k所指出的,还有其他结构,例如哈希表,可以使搜索 O(1)。构建表格是 O(n),非常简单 - 只需迭代边缘列表并将它们放入。