在DAG中查找给定长度N的路径

时间:2018-05-02 19:17:08

标签: algorithm path graph-theory graph-algorithm directed-acyclic-graphs

您将获得一个有向无环图,这是一个有根的树(因此所有边都向下,并且没有两条从根开始的路径可以相交)。您知道图中每条边的长度。我正在寻找一种算法来检查在线性时间内是否存在一些长度为N 的路径。

我正在考虑将图形转换为拓扑顺序,然后只是遍历每个顶点,同时跟踪在给定顶点开始的所有路径。我不确定这是否是正确的解决方案。我可以获得更好的帮助吗?

1 个答案:

答案 0 :(得分:0)

由于您的树是定向的并且不能具有上下路径,因此以下是树的节点数的线性解决方案。

如果我们首先考虑一个更简单的问题,我觉得这更容易解释:给定一个数组DispatchQueue.main.async { //code Here } ,找出是否有一个总和为a的子数组。

我们会使用前缀总和:

N

然后,我们的想法是针对每个s[0] = a[0] s[i > 0] = s[i - 1] + a[i] 检查0 <= i < a.len是否包含值s[j < i]p。重写一下,我们得到s[i] - p == N

一个天真的实现将是:

p == s[i] - N

但是,我们可以使用s[0] = a[0] if a[0] == N: found it! for i = 1 to a.len: s[i] = s[i-1] + a[i] for j = 0 to i: if s[j] == s[i] - N: found it! 解决方案的字典替换嵌套的for循环。

我们需要为树实现相同的解决方案,在深度优先搜索期间构建该字典,但在从递归调用返回时要注意从中删除元素:

O(a.len log a.len) / O(a.len)

初始通话:DFS(node, sums_dict, current_sum): if current_sum - N in sums_dict: found it! else: sums_dict.add(current_sum) for c in node.children: DFS(c, sums_dict, current_sum + c.edge_len) sums_dict.remove(current_sum)

时间复杂度:DFS(root, <empty>, 0),其中O(T * D)是树中的节点数,T是字典的复杂程度:DO(log T)