当前位置: 首页 > news >正文

穿越数据森林与网络迷宫:树与图上动态规划实战指南

在 C++ 算法的浩瀚宇宙中,树与图就像是神秘的迷宫和茂密的森林,充满了未知与挑战。而动态规划则是我们探索其中的神奇罗盘,帮助我们找到最优路径。今天,就让我们一起深入这片神秘领域,揭开树与图上动态规划的神秘面纱!​

树与图上动态规划的独特魅力​

与线性动态规划相比,树与图上的动态规划更加复杂,因为它们的结构不再是简单的线性,而是具有分支和循环。但正是这种复杂性,让它们能够解决更多现实世界中的问题,比如城市交通网络的最优路线规划、社交网络中的信息传播分析等。在树与图上使用动态规划,就像是在错综复杂的迷宫中,通过标记一个个关键点(状态),找到从起点到终点的最佳路径(最优解)。​

树结构上的动态规划​

树结构天然具有递归和层次的特性,这使得树的动态规划通常从叶子节点向根节点进行状态转移。我们以 “树的最大路径和” 问题为例来深入理解。​

问题描述​

给定一棵二叉树,找到从树中某个节点到其他节点的路径中,节点值之和最大的路径。路径可以从任意节点开始,到任意节点结束。​

代码示例​

#include <iostream>
#include <algorithm>
using namespace std;// 定义二叉树节点结构
struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};int maxPathSum(TreeNode* root, int& maxSum) {if (root == nullptr) {return 0;}// 递归计算左子树的最大贡献值int leftMax = max(0, maxPathSum(root->left, maxSum));// 递归计算右子树的最大贡献值int rightMax = max(0, maxPathSum(root->right, maxSum));// 计算经过当前节点的路径和int currentPathSum = root->val + leftMax + rightMax;// 更新全局最大路径和maxSum = max(maxSum, currentPathSum);// 返回当前节点能为父节点提供的最大贡献值return root->val + max(leftMax, rightMax);
}int maxPathSum(TreeNode* root) {int maxSum = INT_MIN;maxPathSum(root, maxSum);return maxSum;
}

代码解释​

  1. 首先定义了二叉树节点的结构体 TreeNode ,包含节点值 val 以及左右子节点指针 left 和 right 。​
  1. maxPathSum(TreeNode* root, int& maxSum) 函数用于递归计算以 root 为根节点的子树的最大路径和。它有两个返回值相关的操作:​
  • 函数内部计算当前节点能为父节点提供的最大贡献值。这是通过比较左子树和右子树的最大贡献值(如果为负数则取 0,因为负数不会增加路径和的大小),再加上当前节点的值得到的。比如,leftMax = max(0, maxPathSum(root->left, maxSum)); 就是计算左子树的最大贡献值。​
  • 同时,计算经过当前节点的路径和,即当前节点值加上左子树和右子树的最大贡献值,如 int currentPathSum = root->val + leftMax + rightMax; ,并更新全局最大路径和 maxSum 。​
  1. 外层的 maxPathSum(TreeNode* root) 函数初始化全局最大路径和为最小值 INT_MIN ,然后调用内部递归函数计算并返回最终的最大路径和。​

图结构上的动态规划​

图的动态规划通常需要处理节点之间复杂的连接关系,常见的有拓扑排序结合动态规划来解决有向无环图的问题,或者使用记忆化搜索处理一般图。我们以 “有向无环图的最长路径” 问题为例。​

问题描述​

给定一个有向无环图(DAG),图中节点带有权值,找到从某个起点到其他节点的最长路径长度。​

代码示例​

#include <iostream>
#include <vector>
#include <queue>
using namespace std;// 拓扑排序 + 动态规划求有向无环图的最长路径
int longestPathInDAG(vector<vector<pair<int, int>>>& graph, int start) {int n = graph.size();vector<int> indegree(n, 0);  // 入度数组vector<int> dp(n, 0);  // dp[i]表示从起点到节点i的最长路径长度queue<int> q;// 统计每个节点的入度for (int i = 0; i < n; ++i) {for (auto& edge : graph[i]) {indegree[edge.first]++;}}// 将入度为0的节点入队for (int i = 0; i < n; ++i) {if (indegree[i] == 0) {q.push(i);}}while (!q.empty()) {int node = q.front();q.pop();for (auto& edge : graph[node]) {int nextNode = edge.first;int weight = edge.second;// 更新到下一个节点的最长路径长度dp[nextNode] = max(dp[nextNode], dp[node] + weight);indegree[nextNode]--;if (indegree[nextNode] == 0) {q.push(nextNode);}}}int maxPath = 0;for (int i = 0; i < n; ++i) {maxPath = max(maxPath, dp[i]);}return maxPath;
}

代码解释​

  1. 首先定义了图的存储结构 vector<vector<pair<int, int>>> ,其中 graph[i] 存储了节点 i 所有的出边,每个 pair 表示目标节点和边的权值。​
  1. 使用 indegree 数组统计每个节点的入度,dp 数组用于记录从起点到每个节点的最长路径长度。​
  1. 通过拓扑排序将入度为 0 的节点入队,然后不断从队列中取出节点,更新其邻接节点的最长路径长度(如 dp[nextNode] = max(dp[nextNode], dp[node] + weight); ),并减少邻接节点的入度。当邻接节点入度变为 0 时,将其入队。​
  1. 最后遍历 dp 数组,找出最长路径长度并返回。​

树与图上的动态规划充满了挑战与乐趣,它们在数据结构和算法的世界中扮演着重要角色。通过不断练习和思考,你会发现自己在这片神秘领域中越来越游刃有余。快去探索更多有趣的问题,用动态规划解开它们的奥秘吧!​

http://www.xdnf.cn/news/264925.html

相关文章:

  • 深拷贝与浅拷贝的核心区别
  • 【unity游戏开发——Animator动画】Animation动画资源节约、优化、编辑修改小技巧
  • 人工智能:如何快速筛选出excel中某列存在跳号的单元格位置?
  • Manus联合创始人:公司产品基于Claude和阿里千问大模型开发
  • Java开发经验——ali编码规范经验总结
  • java面向对象编程【高级篇】之特殊类
  • 【Java多线程】计时器Timer/ScheduledExecutorService的使用
  • mysql主从复制搭建,并基于‌Keepalived + VIP实现高可用
  • MARM:推荐系统中的记忆增强突破
  • C++ - 数据容器之 forward_list(创建与初始化、元素访问、容量判断、元素遍历、添加元素、删除元素)
  • Python爬虫实战:获取企信网指定公司基本工商数据并分析,为客户选择公司做参考
  • 封装pinia并引入pinia持久化工具(pinia-plugin-persistedstate)
  • HarmonyOS NEXT——DevEco Studio的使用(还没写完)
  • 如何基于HAL库进行STM32开发
  • 华为云Flexus+DeepSeek征文|DeepSeek-V3商用服务开通教程
  • Python 学习
  • 4.29-4.30 Maven+单元测试
  • 【LeetCode Hot100】二分查找篇
  • Swift:重构开发范式的现代编程语言
  • 《高性能MySQL》第1讲:MySQL架构
  • 音视频开发技术总结报告
  • 对比表格:数字签名方案、密钥交换协议、密码学协议、后量子密码学——密码学基础
  • 3.0/Q1,Charls最新文章解读
  • batch normalization和layer normalization区别
  • 循环缓冲区
  • QNAP Duplicati 备份 123云盘
  • Java接口全面教程:从入门到精通
  • ai之paddleOCR 识别PDF python312和paddle版本冲突 GLIBCXX_3.4.30
  • C与指针4——指针
  • 每天一道面试题@第五天