树形DP分析

news/2024/10/30 9:37:54/

树形dp


简单来说树形 d p 就是在树上做 d p 罢了 简单来说树形dp就是在树上做dp罢了 简单来说树形dp就是在树上做dp罢了
树嘛,就要符合除了根节点外每个节点只有一个父节点 树嘛,就要符合除了根节点外每个节点只有一个父节点 树嘛,就要符合除了根节点外每个节点只有一个父节点
然后分析 d p 的时候,不再是线性的前几的什么属性那种线性术语了 然后分析dp的时候,不再是线性的前几的什么属性那种线性术语了 然后分析dp的时候,不再是线性的前几的什么属性那种线性术语了
而是以 i 为根节点的树的各种属性 而是以i为根节点的树的各种属性 而是以i为根节点的树的各种属性
状态转移也从原本的前 i − 1 到前 i 个转移 状态转移也从原本的前i-1到前i个转移 状态转移也从原本的前i1到前i个转移
而是 u 的子树向 u 为根的树转移 而是 u的子树向u为根的树转移 而是u的子树向u为根的树转移


上几道例题具体分析
例题一

思路

在这里插入图片描述

AC代码


#include<bits/stdc++.h>using namespace std;const int N = 1e4 + 10;int h[N], e[N], w[N], ne[N], idx;
bool st[N];
int n;
int f[N][3]; //1:最长 0 次长
int res = -0x3f3f3f3f;void add(int a, int b, int c){e[idx] = b;ne[idx] = h[a];w[idx] = c;h[a] = idx ++;
}void dfs(int u)
{for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];dfs(j);if(f[j][1] + w[i] >= f[u][1]){f[u][0] = f[u][1];f[u][1] = f[j][1] + w[i];}else if(f[j][1] + w[i] > f[u][0]){f[u][0] = f[j][1] + w[i];}}
}int main()
{cin >> n;memset(h, -1, sizeof(h));for(int i = 1; i <= n - 1; i ++){int a, b, c;cin >> a >> b >> c;add(a, b, c);st[b] = true;}int root = 1;while(st[root]) root ++;dfs(root);for(int i = 1; i <= n; i ++){res = max(res, f[i][0] + f[i][1]);}cout << res << endl;return 0;
}

例题2
在这里插入图片描述


#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;int h[N], e[N<<1], w[N<<1], ne[N<<1], idx;
int n;
int down1[N], down2[N], up[N], best[N], second[N];void add(int a, int b, int c)
{e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx ++;
}void dfs_d(int u, int fa)
{for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(j == fa) continue;dfs_d(j, u);if(down1[j] + w[i] >= down1[u]){down2[u] = down1[u];second[u] = best[u];best[u] = j;down1[u] = down1[j] + w[i];}else if(down1[j] + w[i] > down2[u]){down2[u] = down1[j] + w[i];second[u] = j;}}
}void dfs_u(int u, int fa)
{for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(j == fa) continue;if(j == best[u]){up[j] = max(up[u], down2[u]) + w[i];}else{up[j] = max(up[u], down1[u]) + w[i];}dfs_u(j, u);}
}int main()
{memset(h, -1, sizeof(h));cin >> n;for(int i = 1; i <= n - 1; i ++){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);}dfs_d(1, -1);dfs_u(1, -1);int res = 1e9;for(int i = 1; i <= n; i ++){res = min(max(down1[i], up[i]), res);}cout << res << endl;return 0;
}


http://www.ppmy.cn/news/50800.html

相关文章

微信小程序PHP+python+nodejs+springboot+vue 电影院订票选座系统

管理员的主要功能有&#xff1a; 1.管理员输入账户登陆后台 2.个人中心&#xff1a;管理员修改密码和账户信息 3.会员管理&#xff1a;对注册的会员信息进行删除&#xff0c;查询&#xff0c;添加&#xff0c;修改 4.电影分类管理&#xff1a;对电影的分类信息进行添加&#xf…

Canokey Pigeon的初级玩法

Canokey Pigeon的初级玩法 前言开箱使用控制台新版旧版 初步设置FIDO2 PIN更改重置 坑&#xff08;或者说不满意的地方&#xff09;玩法FIDO2/U2FOpenPGPPIVNDEFOATH 参考 本文转载于我的博客Canokey Pigeon的初级玩法 Canokey Pigeon今天终于到货了 {% note warning flat %} …

pt12pymsql使用

pymysql模块 pymysql是一个第三方库&#xff0c;如果自己的计算机上没有可以在终端使用命令进行安装。 pymysql默认开始事务&#xff0c;支持事务的引擎需要commit sudo pip3 install pymysql pymysql使用流程 1. 建立数据库连接&#xff1a;db pymysql.connect(...)…

[oeasy]python0140_导入_import_from_as_namespace_

导入import 回忆上次内容 上次学习了 tryexcept 注意要点 半角冒号缩进输出错误信息 有错就报告 不要隐瞒否则找不到出错位置还可以用traceback把 系统报错信息原样输出 但是代码量好多啊 10多 行了 &#x1f92f;可以把他输入部分和输出部分么&#xff1f;&#x1f914; 我…

字符串总结

一、最长公共前缀 1.方法一&#xff1a;横向扫描 class Solution { public:string longestCommonPrefix(vector<string>& strs) {if (!strs.size()) {return "";}string prefix strs[0];int count strs.size();for (int i 1; i < count; i) {prefix…

『网络基础 一 』

目录 网络发展 认识 “协议” 网络协议初始 协议分层 OSI七层模型 TCP/IP五层&#xff08;或四层&#xff09;模型 网络传输基本流程 ​编辑 协议报头 数据包封装和分用 网络中的地址管理 认识IP地址 认识MAC地址 网络发展 独立设计&#xff1a;计算机之间的相互独立…

【操作系统】原语操作详解

基本概念 "原语"一词源于英文 “primitive” 或 “instruction”&#xff0c;意为 “原始的” 或 “基本的指令”。在计算机科学中&#xff0c;原语是一种基本的操作&#xff0c;它是不可分割的&#xff0c;要么全部执行成功&#xff0c;要么全部执行失败&#xff0…

搜索引擎找外贸客户

说起搜索引擎&#xff0c;我们每个人都不陌生&#xff0c;也许第一时间就能想到平日经常使用的“百度一下”和凭借强大算法及丰富功能占据近85%市场份额的谷歌搜索&#xff08;Statista 2023年1月数据&#xff09;这些耳熟能详的搜索引擎。对于外贸人而言搜索引擎也是非常实用的…