Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 树中节点值大于或等于K的不同路径数_Python 3.x_Algorithm_Tree_Graph Theory_N Ary Tree - Fatal编程技术网

Python 3.x 树中节点值大于或等于K的不同路径数

Python 3.x 树中节点值大于或等于K的不同路径数,python-3.x,algorithm,tree,graph-theory,n-ary-tree,Python 3.x,Algorithm,Tree,Graph Theory,N Ary Tree,问题陈述: 给您一个整数N,表示该树中的节点数。现在,您需要计算树中有多少不同的路径,使得该路径中的最小节点值大于或等于k 输入格式: 第一行包含该树中的节点总数N和 正整数值K。 接下来的N-1行包含一对整数u,v值不是逗号分隔的,这表示树中节点u和v之间有一条边。 例如: 输入: 预期产出: 编辑:我想不出如何解决这个问题。所以,请给我一个提示,以便我可以进一步尝试实现它。 即使是最轻微的帮助,我也会非常感激的 更新: 在任何情况下,解决这一问题的幼稚方法都是行不通的。解决方案的复杂性应该在

问题陈述: 给您一个整数N,表示该树中的节点数。现在,您需要计算树中有多少不同的路径,使得该路径中的最小节点值大于或等于k

输入格式:

第一行包含该树中的节点总数N和 正整数值K。 接下来的N-1行包含一对整数u,v值不是逗号分隔的,这表示树中节点u和v之间有一条边。 例如:

输入:

预期产出:

编辑:我想不出如何解决这个问题。所以,请给我一个提示,以便我可以进一步尝试实现它。 即使是最轻微的帮助,我也会非常感激的

更新:


在任何情况下,解决这一问题的幼稚方法都是行不通的。解决方案的复杂性应该在**2或Onlogn上。

让我们在更简单的情况下解决这个问题,假设树中的所有节点都大于k,因此有效路径的数量为nC2

并且,我们还观察到,一条有效路径不能包含任何小于k的节点,因此,我们需要从树中删除所有小于k的节点,这将创建n-k子树,因此最终结果将是

结果=所有子树的nC2之和

简单算法:

remove all edges that connect to nodes that less than k

for each node that >= k and not marked as visited
  do bfs to count number of node in that subtree
  result += nC2

return result

让我们在一个更简单的情况下解决这个问题,假设树中的所有节点都大于k,那么有效路径的数量是nC2

并且,我们还观察到,一条有效路径不能包含任何小于k的节点,因此,我们需要从树中删除所有小于k的节点,这将创建n-k子树,因此最终结果将是

结果=所有子树的nC2之和

简单算法:

remove all edges that connect to nodes that less than k

for each node that >= k and not marked as visited
  do bfs to count number of node in that subtree
  result += nC2

return result

这个问题可以用树上的动态规划来解决,你们可以在这里阅读

让我们将问题分为两部分,第一部分是查找在节点u的子树中有效的路径数。第二部分是对节点U的求解,如果我们不考虑它的子树,而是去它的父节点等等。

让我们把1作为树的根。< /P> 现在,为了解决第一部分,我们将在[]中创建一个数组,在其中存储 节点u的子树中的路径数,因此[u]中的路径数将表示从节点u开始并访问其子树的有效路径数。要计算此数组,我们可以运行一个简单的dfs,如下所示:

//u is the current node - p is the parent
void dfs1(int u, int p) {
    for (int i = 0; i < g[u].size(); i++) { //iterate through the adjacency of node u
        int v = g[u][i]; // v is the child of u
        if (v != p) { //in case v is the parent just ignore it
            dfs1(v, u); //go to node v
            if (u >= k && v >= k) { //if value of u or v is less than k then we cant start at this node so it should be 0
                in[u] += in[v] + 1; //add to number of paths of u the number of paths starting from the node v + 1 (+1 because we can also go from u to v)
            }
        }
    }
}
要找到答案,只需对所有节点求和[u]+in[u],然后除以2,因为每条路径计算了两次


复杂度OV+E

这个问题可以用树上的动态规划来解决,你可以在这里阅读

让我们将问题分为两部分,第一部分是查找在节点u的子树中有效的路径数。第二部分是对节点U的求解,如果我们不考虑它的子树,而是去它的父节点等等。

让我们把1作为树的根。< /P> 现在,为了解决第一部分,我们将在[]中创建一个数组,在其中存储 节点u的子树中的路径数,因此[u]中的路径数将表示从节点u开始并访问其子树的有效路径数。要计算此数组,我们可以运行一个简单的dfs,如下所示:

//u is the current node - p is the parent
void dfs1(int u, int p) {
    for (int i = 0; i < g[u].size(); i++) { //iterate through the adjacency of node u
        int v = g[u][i]; // v is the child of u
        if (v != p) { //in case v is the parent just ignore it
            dfs1(v, u); //go to node v
            if (u >= k && v >= k) { //if value of u or v is less than k then we cant start at this node so it should be 0
                in[u] += in[v] + 1; //add to number of paths of u the number of paths starting from the node v + 1 (+1 because we can also go from u to v)
            }
        }
    }
}
要找到答案,只需对所有节点求和[u]+in[u],然后除以2,因为每条路径计算了两次


复杂度OV+E

对于树,假设我们枚举的路径是从上到下的,我们可以递归地表示它。设fT,k表示元组[a,b],其中a是T中从T开始的不同有效路径的数目;和b,T中从较低节点开始的不同有效路径的数量。有效路径中的所有节点的值都大于或等于k

然后是Python代码:

def fT,k: 如果不是T[儿童]: 返回[0,0] 结果=[0,0] 对于T中的c[儿童]: [a,b]=fc,k 结果[1]+=a+b
如果T[value]>=k对于树,假设我们枚举的路径是从上到下的,我们可以递归地表示它。设fT,k表示元组[a,b],其中a是T中从T开始的不同有效路径的数目;和b,T中从较低节点开始的不同有效路径的数量。有效路径中的所有节点的值都大于或等于k

然后是Python代码:

def fT,k: 如果不是T[儿童]: 返回[0,0] 结果=[0,0] 对于T中的c[儿童]: [a,b]=fc,k 结果[1]+=a+b
如果T[value]>=k@•㪞דברקן,我只想确定一种方法,以获得从根节点到子节点的所有可能路径,以最小的复杂性满足给定的约束。如果有相同的算法,那么我可以使用n轻松确定子路径的总数

C2,其中n是该不同路径中节点总数的计数。在问题中,它在哪里表示根节点到子节点?它只是说,不同的路径。。。在树上…是的,你是对的。但在树中,节点之间存在层次关系。因此,我使用根节点到子节点。考虑一棵树有20个节点。从起始节点到结束节点的一条路径共有5个节点,且所有节点都满足给定的约束条件。因此,可以很容易地说,该路由中不同路径的总数将为5C2。请使用根以外的术语来描述路径的起点。这太令人困惑了:我无法理解你之前的评论。和主持人在那里-请停止移动评论聊天时,评论相关的问题适当@我只想确定一种方法,以获得从根节点到子节点的所有可能路径,以最小的复杂性满足给定约束。如果有相同的算法,那么我可以使用nC2轻松确定子路径的总数,其中n是该不同路径中节点总数的计数。在问题中,它在哪里表示根节点到子节点?它只是说,不同的路径。。。在树上…是的,你是对的。但在树中,节点之间存在层次关系。因此,我使用根节点到子节点。考虑一棵树有20个节点。从起始节点到结束节点的一条路径共有5个节点,且所有节点都满足给定的约束条件。因此,可以很容易地说,该路由中不同路径的总数将为5C2。请使用根以外的术语来描述路径的起点。这太令人困惑了:我无法理解你之前的评论。和主持人在那里-请停止移动评论聊天时,评论相关的问题适当!我想,这是迄今为止最合适的解决办法。。我正在等待更多专家对这种方法的评论,因为我无法决定它是最好的方法还是更好的方法仍然存在。假设树中的所有节点都大于k,那么有效路径的数量是nC2-输入k=1,1->2,2->3,1->4,4->5如何选择2=10,但是我们只有3+3个不同的有效路径。我误解你的回答了吗?顺便说一下,我添加了一个递归答案。@1->2,1->3,1->4,1->5,2->3,2->4,2->2->5,3->4,3->5。我错过了什么吗?是的,你错过了什么。在我上面评论中的示例中,5或4无法从2访问。@?但我认为这不是定向的,因为没有定向树的概念,问题陈述是节点u和v之间的边,而不是从u到v的边,这里没有暗示方向。我想,这是迄今为止最合适的解决方案。。我正在等待更多专家对这种方法的评论,因为我无法决定它是最好的方法还是更好的方法仍然存在。假设树中的所有节点都大于k,那么有效路径的数量是nC2-输入k=1,1->2,2->3,1->4,4->5如何选择2=10,但是我们只有3+3个不同的有效路径。我误解你的回答了吗?顺便说一下,我添加了一个递归答案。@1->2,1->3,1->4,1->5,2->3,2->4,2->2->5,3->4,3->5。我错过了什么吗?是的,你错过了什么。在我上面评论中的示例中,5或4无法从2访问。@?但我认为这不是定向的,因为没有定向树的概念,问题陈述是节点u和v之间的边,不是从u到v的边,这里没有暗示方向。
//u is the current node - p is the parent
void dfs1(int u, int p) {
    for (int i = 0; i < g[u].size(); i++) { //iterate through the adjacency of node u
        int v = g[u][i]; // v is the child of u
        if (v != p) { //in case v is the parent just ignore it
            dfs1(v, u); //go to node v
            if (u >= k && v >= k) { //if value of u or v is less than k then we cant start at this node so it should be 0
                in[u] += in[v] + 1; //add to number of paths of u the number of paths starting from the node v + 1 (+1 because we can also go from u to v)
            }
        }
    }
}
// u is the current node - p is the parent
void dfs2(int u, int p) {
    for (int i = 0; i < g[u].size(); i++) { // iterate through the adjacency of node u
        int v = g[u][i]; // v is the child of u
        if (v != p) { // in case v is the parent just ignore it
            if (v >= k && u >= k) { // if value of u or v is less than k then we cant start at this node so it should be 0
                out[v] += (out[u] + 1); //add to the number of paths of v the number of paths from it's parent (u) + 1 if we dont use the subtree of u
                out[v] += (in[u] - in[v] - 1); // add to the number of paths of v the number of paths from it's parent (u)
                // we should subtract in[v] + 1 because we want to exclude this branch from the subtree of the parent
            }
            dfs2(v, u); // go to node v
        }
    }
}