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

在 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.mzph.cn/web/78354.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UDP / TCP 协议

目录 一、前言&#xff1a; 数据封装与分用&#xff1a; 二、网络协议分层模型&#xff1a; 三、UDP / TCP 协议 UDP 协议&#xff1a; 1、UDP 协议段格式&#xff1a; 2、UDP 的特点&#xff1a; TCP 协议&#xff1a; 1、TCP 协议段格式&#xff1a; 2、TCP 协议的十…

Python 实现的运筹优化系统数学建模详解(动态规划模型)

相关代码链接&#xff1a;https://download.csdn.net/download/heikediguoshinib/90713747?spm1001.2014.3001.5503 一、引言 在计算机科学与数学建模的广阔领域中&#xff0c;算法如同精密的齿轮&#xff0c;推动着问题的解决与系统的运行。当面对复杂的优化问题时&…

langfuse本地安装

目录 安装命令项目准备用openai测试 安装命令 本地&#xff08;docker compose&#xff09;&#xff1a;使用 Docker Compose 在你的机器上于 5 分钟内运行 Langfuse。 # 获取最新的 Langfuse 仓库副本 git clone https://github.com/langfuse/langfuse.git cd langfuse# 运行 …

每天学一个 Linux 命令(35):dos2unix

每天学一个 Linux 命令(35):dos2unix 命令简介 dos2unix 是一个用于将 Windows/DOS 格式的文本文件转换为 Unix/Linux 格式的实用工具。它主要处理行尾符的转换(将 CRLF 转换为 LF),同时也能处理编码问题和字符集转换。这个命令在跨平台文件共享、代码迁移和系统管理场…

第6章 Python 基本数据类型详解(int, float, bool, str)细节补充

文章目录 Python 基本数据类型深入解析(int, float, bool, str)一、整型(int)的底层机制二、浮点型(float)的陷阱与解决方案三、布尔型(bool)的底层本质四、字符串(str)的不可变性与优化五、类型间的隐式转换与陷阱六、性能优化与工具总结:关键细节与最佳实践Python…

19. LangChain安全与伦理:如何避免模型“幻觉“与数据泄露?

引言&#xff1a;当AI成为企业"数字员工"时的责任边界 2025年某金融机构因AI客服泄露用户信用卡信息被罚款2300万美元。本文将基于LangChain的安全架构与Deepseek-R1的合规实践&#xff0c;揭示如何构建既强大又安全的AI系统。 一、AI安全风险矩阵 1.1 2025年最新威…

Java快速上手之实验六

1. 编写ItemEventDemo.java&#xff0c;当选中或取消选中单选钮、复选钮和列表框时显示所选的结果。 2&#xff0e;编写GUIExample.java&#xff0c;当选中或取消选中单选钮、复选钮时在标签中显示相应结果。 import javax.swing.*; import java.awt.*; import java.awt.event.…

QT6 源(72):阅读与注释单选框这个类型的按钮 QRadioButton,及各种属性验证,

&#xff08;1&#xff09;按钮间的互斥&#xff1a; &#xff08;2&#xff09;源码来自于头文件 qradiobutton . h &#xff1a; #ifndef QRADIOBUTTON_H #define QRADIOBUTTON_H#include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qabstractbutton.h>…

【算法滑动窗口】 将x减到0的最小操作数

将x减到0的最小操作数 个人总结的八步归纳AI的归纳**8步归纳法&#xff08;极简直白版&#xff09;**1. 问题本质2. 问题特征3. 切入点4. 解决流程5. 每步目标与操作6. 注意事项7. 最终目标8. 整体总结 代码对照&#xff08;逐行解析&#xff09;举个栗子&#x1f330;**一句话…

RISC-V GPU架构研究进展:在深度学习推理场景的可行性验证

一、新型算力架构的突围战 在英伟达CUDA生态主导的GPU市场中&#xff0c;RISC-V架构正以‌开源基因‌和‌模块化设计‌开辟新赛道。当前主流GPU架构面临两大痛点&#xff1a; 指令集封闭性‌&#xff1a;NVIDIA的SASS指令集与AMD的GCN/RDNA架构均采用私有指令编码&#xff0c…

LVGL -滑动条

1 滑动条 LVGL 的滑动条(Slider)是一个非常有用的控件,允许用户通过拖动滑块或点击滑条来选择一个值。 1.1 基本定义 滑动条允许用户在一个预定义的数值范围内选择一个特定的值。它通常由一个轨道(track)和一个滑块(thumb)组成。用户可以通过点击或拖动滑块来调整数值。…

ROS2学习笔记|Python实现订阅消息并朗读的详细步骤

本教程将详细介绍如何使用 ROS 2 实现一个节点订阅另一个节点发布的消息&#xff0c;并将接收到的消息通过 espeakng 库进行朗读的完整流程。以下步骤假设你已经安装好了 ROS 2 环境&#xff08;以 ROS 2 Humble 为例&#xff09;&#xff0c;并熟悉基本的 Linux 操作。 注意&…

WPF封装常用的TCP、串口、Modbus、MQTT、Webapi、PLC通讯工具类

WPF封装常用通讯工具类 下面我将为您封装常用的TCP、串口、Modbus、MQTT、WebAPI和PLC通讯工具类,适用于WPF应用程序开发。 一、TCP通讯工具类 using System; using System.Net.Sockets; using System.Text; using System.Threading.Tasks;public class TcpClientHelper : …

npm pnpm yarn 设置国内镜像

国内镜像 常用的国内镜像&#xff1a; 淘宝镜像 https://registry.npmmirror.com 腾讯云镜像​​ https://mirrors.cloud.tencent.com/npm/ 华为云镜像​​ https://repo.huaweicloud.com/repository/npm/ CNPM&#xff08;阿里系&#xff09; ​​ https://r.cnpmjs.org/ 清华…

P4552 [Poetize6] IncDec Sequence 题解

P4552 [Poetize6] IncDec Sequence - 洛谷 差分贪心 根据题目&#xff1a;一段区间都加1或减1 &#xff0c; 可以想到差分 构建差分数组&#xff1a;sub 我们要让除了sub[1] , 其他全是0 我们可以的操作是&#xff1a;l1 , r-1 or l-1 , r1 or 一个数1 / -1 所…

Power Query精通指南2:数据转换——透视/逆透视/分组、横向纵向合并数据、条件判断、处理日期时间

文章目录 七、常见数据转换7.1 逆透视7.1.1 逆透视操作7.1.2 重建透视表&#xff0c;更新数据7.1.3 三种逆透视方式&#xff08;逆透视列等价于逆透视其他列&#xff09; 7.2 透视7.3 拆分列7.3.1 将列拆分为多列7.3.2 将列拆分为多行7.3.3 拆分到列后逆透视&#xff08;保留列…

使用线性表实现通讯录管理

目录 &#x1f680;前言&#x1f99c;任务目标&#x1f31f;顺序表实现&#x1f40d;链表实现 &#x1f680;前言 大家好&#xff01;我是 EnigmaCoder。 本文介绍线性表的实验&#xff0c;使用顺序表和链表实现通讯录管理&#xff0c;包含初始化、插入、删除、查询、输出。 &a…

firewall docker 冲突问题解决(亲测有效)

# 关闭iptables&#xff0c;使用firewall systemctl disable iptables # 禁用服务 systemctl stop iptables # 关闭服务 systemctl status iptables # 查看服务状态 systemctl enable firewalld # 设置防火墙开机自启动 systemctl start firewalld # 开启服务 systemctl s…

[250428] Nginx 1.28.0 发布:性能优化、安全增强及新特性

目录 Nginx 1.28.0 稳定版发布主要亮点包括&#xff1a;功能增强&#xff1a;安全性改进&#xff1a;其他&#xff1a; Nginx 1.28.0 稳定版发布 Nginx 官方于 4 月 24 日发布了最新的 1.28.0 稳定版本。此版本基于之前的 1.27.x 主线分支&#xff0c;整合了多项新功能、性能优…

昇腾的CANN是什么?跟英伟达CUDA的有什么联系和区别?【浅谈版】

昇腾的CANN&#xff08;Compute Architecture for Neural Networks&#xff09;是华为专门为AI场景设计的异构计算架构&#xff0c;类似于英伟达的CUDA&#xff0c;但它针对的是华为自家的昇腾AI处理器&#xff08;Ascend系列&#xff09;。简单来说&#xff0c;CANN的作用是连…