树中所有对最短路径之和

树中所有对最短路径之和

中,“所有节点对最短路径之和”的术语指的是计算所有节点对的个别最短路径的总和。一种有效的方法是使用双重DFS(深度优先搜索)算法。在第一次DFS遍历期间确定所选节点与每个其他节点之间的距离。在第二次DFS遍历期间再次遍历树,将每个节点视为潜在的LCA(最低公共祖先),并计算所选LCA的后代节点对之间的距离之和。使用这种方法可以计算出树中所有节点对最短路径之和,并确保得到一个理想的解决方案

使用的方法

双重 DFS(深度优先搜索)方法

动态规划方法

双重 DFS(深度优先搜索)方法

对于树中所有对最短路径的总和,我们使用双重 DFS(深度优先搜索)方法,该方法涉及两次 DFS 遍历。首先,我们计算从任何节点开始到所有其他节点的距离。然后,在第二次 DFS 遍历期间,我们导航树,同时将每个节点视为潜在的 LCA。我们在遍历时计算并求和作为所选 LCA 后代的节点对之间的距离。通过对所有节点重复此过程,我们获得所有对最短路径的总和。该策略对于这个问题非常引人注目,因为它有效地计算了树中所有节点集之间的距离总和。

算法

树中的任何节点都可以作为起始节点

为了确定从选择的起始节点到所有其他节点的距离,从该节点开始执行深度优先搜索(DFS)。这些距离应该保存在一个数组或数据结构中。

接下来,在树上运行第二次深度优先搜索(DFS),将每个节点视为可能的最近公共祖先(LCA)

在第二次 DFS 期间遍历树时,计算作为所选 LCA 后代的节点对之间的距离。对于每个 LCA,将这些距离加在一起。

对树中的每个节点重复此过程

树中最有限方式的所有匹配的总和由步骤 4 中所有计算距离的总和表示。

Example

的中文翻译为:

示例

#include #include using namespace std;const int MAXN = 10005;vector graph[MAXN];int ancestor[MAXN];int dfs(int node, int lca, int distance) {   int sum = 0;   for (int neighbor : graph[node]) {      if (neighbor != lca) {         sum += dfs(neighbor, lca, distance + 1);      }   }   return sum + distance;}int main() {   int lca_node = 0;   int total_sum = 0;   for (int node = 0; node 

输出

Total sum of distances between descendants of the LCA: 0

登录后复制

动态规划方法:

我们首先选择任意一个节点作为根节点,并在动态规划方法中将树转化为有根树,用于计算树中所有节点间最短路径之和。我们利用动态规划计算每个节点与根节点之间的分割,并将结果存储在一个数组中。然后,对于每个节点,我们将其子节点与根节点的分离(已计算)相加,以确定所有其他节点的整体分离。通过这种方式,我们能够快速计算出所有节点间最短路径的总数。作为解决该问题的有效方法,该算法的时间复杂度为O(N),其中N是树中节点的数量。

算法

将树中的任何节点作为根并以树为根(例如,使用根节点的深度搜索)以创建有根树。

动态规划可用于确定每个节点距根的距离。这些距离应该存储在数组或数据结构中。

计算树中每个节点到所有其他节点的距离的总和:

a.遍历当前节点的子节点。

b.要考虑通过当前节点的路径,请将每个子树的子树中的节点数以及之前为每个子树计算的到根的距离相加。

c. 对于活动节点的每个子节点,将这些金额相加

d.将当前节点的总计添加到最终结果中。

树中所有对最短路径的总和就是最终结果。

#include #include using namespace std;struct TreeNode {   int val;   vector children;};int dfs(TreeNode* node, vector& distances) {   int subtree_size = 1;   for (TreeNode* child : node->children) {      subtree_size += dfs(child, distances);      distances[node->val] += distances[child->val] + subtree_size;   }   return subtree_size;}int sumOfAllPairShortestPaths(TreeNode* root) {   vector distances(root->val + 1, 0);   dfs(root, distances);   int total_sum = 0;   for (int distance : distances) {      total_sum += distance;   }   return total_sum;}int main() {   TreeNode* root = new TreeNode{0};   int result = sumOfAllPairShortestPaths(root);   cout 

输出

Sum of all pair shortest paths in the tree: 0

登录后复制

结论

树中所有对最短路径的总和可以使用 Double DFS(深度优先搜索)方法或动态规划来计算。 Double DFS 方法由两遍组成,首先计算从选定节点到所有其他节点的距离,然后再次遍历树,同时将每个节点视为潜在的最低公共祖先 (LCA),以将之间的距离相加后代节点对。动态规划方法需要递归地使用 DFS 来建立树的根并计算从根到每个其他节点的距离。两种方法的结果是相同的,并且由树中所有成对最短路径的总和组成。两种算法之间的决策可能基于特定的实现偏好或树结构,但两种算法都提供了有效的解决方案。

以上就是树中所有对最短路径之和的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2585579.html

(0)
上一篇 2025年3月6日 15:04:47
下一篇 2025年3月6日 15:04:57

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 在C++中的可重构数

    给定一个整数类型的值,假设为number。任务是检查给定的数字是否可重构。如果是,打印该数字是可重构数字,否则打印不可能。 什么是可重构数字? 当一个数字可以被其可用因子的总数整除时,它就是可重构的。例如,数字9是可重构的,因为它有3个因子…

    2025年3月6日
    200
  • 使用C++实现删除所有不在任何路径上且路径和小于k的节点

    在这个问题中,我们有一个二叉树,其从根节点到叶节点的路径是完全定义的。从根节点到叶子节点的所有节点之和必须大于或等于k。所以我们需要删除路径中总和小于k的所有节点。这里要记住的重要一点是,一个节点可能是许多路径的一部分,因此只有当所有路径的…

    2025年3月6日
    200
  • 中心十二边形数

    描绘十二边形的图形数字称为十二边形数。中心十二边形数由中心的一个点和连续十二边形(即 12 边多边形)层中围绕该点的其他点表示。 中心十二边形数可以通过下图更好地解释。 对于n=1,中心只有一个点。因此输出为1。 对于n=2,中心有一个点,…

    2025年3月6日
    200
  • 回文自拍数

    如果一个数字可以仅使用其自己的数字和某些数学运算来表示,则该数字被视为“自拍数字”。 例如,936是一个自拍号码。 $$mathrm{936:=:(sqrt{9})!^{3}:+:6!:=:216:+:720:=:第936章 这里可以看到,…

    2025年3月6日
    200
  • 在一个有向加权图中,求解恰好包含k条边的最短路径

    在协调加权图表中,找到具有精确 k 个边的最简短路径的问题包括确定在精确导航 k 个边时权重最小的路径。这将通过采用动态编程策略来实现,例如采用 3D 框架来存储所有可想到的方式中的最小权重。计算在顶点和边上重复,在每一步都调整最小权重。通…

    2025年3月6日
    200
  • 在C++中的合并排序树

    We are given an integer array, a set of segment start and end pointers and a key value and the problem statement here is…

    2025年3月6日
    200
  • 给定一个数,其与原始数之和等于另一个给定的数的排列方式

    在本文中,我们将深入探讨一个涉及数字和排列的迷人问题:“一个数与原始数的和等于另一个给定数的排列”。这个问题将数论和组合数学独特地结合在一起,使它成为一个引人入胜的挑战。 为了澄清,给定一个原始数和一个目标数,我们需要找到原始数的一个排列,…

    2025年3月6日
    200
  • C++程序以移除不满足路径和大于等于k的节点

    在这个问题中,我们有一个二叉树,其从根节点到叶节点的路径是完全定义的。从根节点到叶节点的所有节点的总和必须大于或等于常数值 k。因此,我们需要删除那些总和小于 k 的路径中的所有节点,这样树中剩下的路径将大于 k。这里要记住的重要一点是,一…

    2025年3月6日
    200
  • 使用弗洛伊德-沃沙尔算法找到任意两个节点之间的最短路径

    c++有一个宏,它被定义为一段代码或期望的值,并且每当用户需要时,它将被重复使用。弗洛伊德-沃尔夏尔算法是在给定的加权图中找到所有顶点对之间最短路径的过程。该算法遵循动态规划的方法来找到最小权重图。 让我们通过图表来理解弗洛伊德-沃尔夏尔算…

    2025年3月6日
    200
  • 递归在 C++ 数据结构中的妙用:栈和树的实现

    递归在 c++++ 数据结构中的应用:栈:通过后进先出 (lifo) 结构递归实现栈。树:通过分层结构递归实现树,支持插入和深度计算等操作。递归为处理嵌套结构提供了简洁高效的解决方案,使数据结构的实现更加直观和易于维护。 递归在 C++ 数…

    2025年3月6日
    200

发表回复

登录后才能评论