树形dp部分题目总结

news/2025/10/30 20:35:23/文章来源:https://www.cnblogs.com/Floydzzy/p/19178094

树形dp还是太难了

No.1 P2664 树上游戏

题目直接点开即可,这里不再赘述

我们发现其实直接统计每条路径上的颜色个数并不好统计,即使拆开贡献也是如此

举个例子,你要统计一个节点的贡献,那么你的贡献区间是不好确定的,因为你并不能快速确定贡献区间端点的同色点都在那里,它们之中既可能包含祖先,也有可能包含祖先的某几个子孙节点

那么我们仔细想一想可以发现,反向来减去贡献似乎是好维护的?

我们选定一种颜色 \(c\) ,并将所有颜色为 \(c\) 的点全部删掉,那么我们就可以得到若干个联通块,显然每个联通块内任意两点之间都不存在贡献,反之则一定存在,我们利用树上差分维护一下每个联通块大小即可

// Problem: P2664 树上游戏
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2664
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Author: Floyd.Uranus
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
typedef long long ll;#define int long longconst int N = 1e5 + 10;#define Floyd mainint inline read () {int x = 0, f = 1; char ch = getchar ();while (ch < '0' || ch > '9') {if (ch == '-') f = -1;ch = getchar ();}while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar ();}return x * f;
}inline void write (int x) {if (x < 0) putchar ('-'), x = -x;if (x > 9) write (x / 10);putchar ('0' + x % 10);return void ();
}ll n, c[N], sum, cnt, vis[N], ans[N], siz[N], lz[N], bj[N], Minus[N];vector <int> e[N];void inline dfs (ll x, ll fa) {siz[x] = 1;ll tmp = Minus[c[fa]];for (auto nxt : e[x]) {if (nxt == fa) continue;dfs (nxt, x);siz[x] += siz[nxt];}Minus[c[x]] ++;if (fa) lz[x] = siz[x] - Minus[c[fa]] + tmp, Minus[c[fa]] += lz[x];return void ();
}void inline getans (int x, int fa) {ll ybj = bj[c[fa]];cnt += lz[x] - bj[c[fa]];bj[c[fa]] = lz[x];ans[x] = n * sum - cnt + bj[c[x]];for (auto nxt : e[x]) {if (nxt == fa) continue;getans (nxt, x);}bj[c[fa]] = ybj;cnt -= lz[x] - bj[c[fa]];return void ();
}void inline solve () {n = read();for (int i = 1; i <= n; ++i) {c[i] = read();if (!vis[c[i]]) vis[c[i]] = 1, sum ++;}for (int i = 1; i < n; ++i) {int a = read(), b = read();e[a].push_back(b), e[b].push_back(a);}dfs (1, 0);for (int i = 1; i <= 100000; ++i) if (vis[i]) cnt += n - Minus[i], bj[i] = n - Minus[i];getans (1, 0);for (int i = 1; i <= n; ++i) write (ans[i]),putchar ('\n');return void ();
}signed Floyd () {int T = 1;while (T--) solve ();return 0;
}

No.2 P3748 [六省联考 2017] 摧毁“树状图”

这道题也是好起来了

比较显然的树形dp,就是状态比较难想,转移有点难推

不妨大胆假设它给出的三种情况对于我们最后的答案均无影响(也即我们只去考虑第一种情况)

敲黑板!状态设计

我们可以想一下,当前我们在一个节点 \(x\) 的时候,如果它的子树内部只有一条链,那么有几种情况?

显然是三种,一种是这条链的一端点为 \(x\) ;另一种是完全包含在某一个子树内部;还有一种就是两个端点都在子树内部,但是经过点 \(x\)

以此类推,我们可以推知两条链的情况

1.两个都完全包含在子树内
2.其中一个经过点 \(x\)

好的,我们接下来根据这个可以去设计一个相对来说比较好转移的状态了

设:

1.\(f_{p, 0}\) 表示点 \(p\) 子树内部含有一条链,且这条链的一个端点为 \(p\) 的答案
2.\(f_{p, 1}\) 表示点 \(p\) 子树内部含有一条链,且这条链并不经过点 \(p\) 的答案
3.\(f_{p, 2}\) 表示点 \(p\) 子树内部含有一条链,这条链经过点 \(p\) 但是 \(p\) 并不是端点的答案
4.\(f_{p, 3}\) 表示点 \(p\) 子树内部有两条链,一条以 \(p\) 为一个端点,另一条完全不经过点 \(p\) 的答案

怎么转移?别急,等我代码

敲黑板!状态转移!

先粘一下代码

	MAX (ans, f[x][3] + f[nxt][0] - (x == 1));MAX (ans, f[x][2] + f[nxt][2] - (x == 1));MAX (ans, f[x][1] + f[nxt][1] - 1);MAX (ans, f[x][0] + f[nxt][3] - (x == 1));MAX (ans, f[x][2] + f[nxt][1] - (x == 1));MAX (ans, f[x][1] + f[nxt][2]);MAX (f[x][1], f[nxt][2] + 1);MAX (f[x][1], f[nxt][1]);MAX (f[x][3], f[nxt][3] + deg[x] - 1);MAX (f[x][3], f[x][0] + f[nxt][2] - 1);MAX (f[x][3], f[x][0] + f[nxt][1] - 1);MAX (f[x][3], f[x][2] + f[nxt][0] - 1);MAX (f[x][3], f[nxt][0] + deg[x] + ret - 2);MAX (f[x][2], f[x][0] + f[nxt][0] - 1);MAX (f[x][0], f[nxt][0] + deg[x] - 1);MAX (ret, max (f[nxt][1], f[nxt][2]));

至于是怎么来的我就不细讲了,留作读者思考,画图会更好理解一些

其中 \(deg_p\) 的意思就是 \(p\) 的儿子数

于是我们就做完了

贴一下完整代码

// Problem: P3748 [六省联考 2017] 摧毁“树状图”
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3748
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// Author: Floyd.Uranus
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
typedef long long ll;const int N = 1e5 + 10;#define Floyd mainint inline read () {int x = 0, f = 1;char ch = getchar ();while (ch < '0' || ch > '9') {if (ch == '-') f = -1;ch = getchar ();}while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar ();}return x * f;
}void inline write (int x) {if (x < 0) putchar ('-'), x = -x;if (x > 9) write (x / 10);putchar ('0' + x % 10);return void ();
}int ans, f[N][4], deg[N], n, T, IDX;
vector <int> e[N];void inline add (int x, int y) {e[x].push_back(y), e[y].push_back(x);return deg[x] ++, deg[y] ++, void ();
}void inline Clear () {for (int i = 1; i <= n; ++i) deg[i] = 0, e[i].clear ();return void ();
}void inline MAX (int &a, int b) {return a = max(a, b), void ();}void inline dp (int x, int fa) {int ret = 0;for (auto nxt : e[x]) {if (nxt == fa) continue;dp (nxt, x);MAX (ans, f[x][3] + f[nxt][0] - (x == 1));MAX (ans, f[x][2] + f[nxt][2] - (x == 1));MAX (ans, f[x][1] + f[nxt][1] - 1);MAX (ans, f[x][0] + f[nxt][3] - (x == 1));MAX (ans, f[x][2] + f[nxt][1] - (x == 1));MAX (ans, f[x][1] + f[nxt][2]);MAX (f[x][1], f[nxt][2] + 1);MAX (f[x][1], f[nxt][1]);MAX (f[x][3], f[nxt][3] + deg[x] - 1);MAX (f[x][3], f[x][0] + f[nxt][2] - 1);MAX (f[x][3], f[x][0] + f[nxt][1] - 1);MAX (f[x][3], f[x][2] + f[nxt][0] - 1);MAX (f[x][3], f[nxt][0] + deg[x] + ret - 2);MAX (f[x][2], f[x][0] + f[nxt][0] - 1);MAX (f[x][0], f[nxt][0] + deg[x] - 1);MAX (ret, max (f[nxt][1], f[nxt][2]));}return void ();
}void inline solve () {ans = 0, n = read();for (int i = 1; i <= IDX; ++i) read(), read();for (int i = 1; i < n; ++ i) add (read(), read()), deg[i + 1] --;for (int i = 1; i <= n; ++i)f[i][0] = f[i][2] = f[i][3] = deg[i], f[i][1] = 1;dp (1, 0);write (ans), putchar ('\n');Clear ();return void ();
}signed Floyd () {T = read(), IDX = read();while (T--) solve ();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/951119.shtml

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

相关文章

人工智能之编程基础 Python 入门:第三章 基础语法

人工智能之编程基础 Python 入门:第三章 基础语法人工智能之编程基础 Python 入门 第三章 基础语法@目录人工智能之编程基础 Python 入门前言一、基本语法第一个程序编码标识符行与缩进注释运算符一、算术运算符(Ari…

模块-文本

模块-文本模块:__init__文件中经常方常用的模块名用于快速导入 匿名函数递归:函数自己调用自己的写法叫递归异常处理 try: except excption as e:(报错执行) else: (没报错执行) finally:(无论是否报错都执行)

oier的呻吟

题记: 得之我幸,失之我命哎,马上就要考csp-j/s了 总感觉没复习好,啥都不会 好累 赛前遗言 如果这次没上,也不知道以后会有没有机会碰oi 那个oier曾没有远大的志向 突然想到那一句话 得之我幸,失之我命可能明后天…

进销存软件和ERP是包含关系吗?

进销存软件和ERP是包含关系吗?很多企业老板都会问我这个问题。 尤其是第一次接触信息化系统的时候,常常听人说:ERP比进销存高级、ERP包含进销存、我们先上个进销存,后面再上ERP。 听起来都对,但很多人其实并不清楚…

jenkins 权限控制(用户只能看指定的项目)

jenkins 权限控制(用户只能看指定的项目)转自:https://www.cnblogs.com/lfxx/p/17394304.html 1、在插件管理下载Role-based Authorization Strategy插件 2、打开全局安全设置,设置授权策略3、在管理角色里新增一个全…

CF1784C Monsters (hard version)

对于添加操作难做考虑时空倒流改为删数。我们先考虑不带修怎么做,显然考虑维护一个指针排序后从左往右扫。如果当前指针如果还是 \(\leq a_i\),则 \(x\leftarrow x+1\),答案加上 \(a_i-x\)。那么我们发现,答案只跟…

[Programming Tips]Teach Yourself Programming in Ten Years by Peter Norvig

https://www.norvig.com/21-days.html中文翻译版: https://web.archive.org/web/20090216071944/http://www.javaresearch.org/article/12568.htm10年编程无师自通FooSleeper 翻译 更新:2005-01-12 10:18:06 版本…

世界上最牛逼的人—黄景行

黄景行是世界上最牛逼的人

X991CN-个人自制计算器

实物图PCB-3D视图硬件架构图:应用处理器: ESP32-S3 CORE: Xtensa LX7 32bit 240MHZ SRAM:320KB SPI-NORFLASH:16MB PSRAM:8MB SPI-NANDFLASH:256MB TF卡(SPI模式) NORFLASH和NANDFLASH均采用6线QSPI模式,由于ESP32-S…

非计算机专业,保姆级申请软著教程

软著对认证高新企业、申请人才政策、或者大学加学分都很有用。 有很多朋友想自己申请软著,但是又不知道怎么申请。 这里小玖给大家分享一下,保姆级申请软著的流程。 一、前期准备 在申请软著前,需要完成一些前期准…

F5重大安全事件:国家级黑客窃取BIG-IP源代码与技术漏洞

网络安全公司F5确认遭受国家级黑客攻击,攻击者窃取了其旗舰产品BIG-IP的源代码和未公开漏洞信息。该事件对全球企业和关键基础设施构成严重威胁,文章详细分析了攻击过程、潜在影响及防御建议。F5重大安全事件:国家级…

2025年功效型洗发水品牌推荐榜:二硫化硒去屑洗发水/香氛洗发水/控油蓬松洗发水/MASIL玛丝兰以科技适配多元洗护需求​

随着消费者头皮护理认知升级,功效型洗发水市场在 2025 年持续扩容,去屑、控油、修护等细分需求日益突出。但市场增长也伴随产品功效参差不齐、成分温和性差异大等问题,消费者在选购时常面临 “功效与温和难兼顾”“…

10.30(续)

代码大全2的11-13章的读后感: 第 11 章谈变量命名,直指 “模糊命名导致的理解成本”:很多人写代码时觉得x“y”“tmp” 够用,可过了半个月回头调试,却要花十分钟回忆x到底代表用户 ID 还是订单编号;而 “名称反映…

Python字典 _ 创个秒查流行语的词典

Python字典 _ 创个秒查流行语的词典#声明字典slang_dict = {}slang_dict["觉醒年代"] = "A"slang_dict["双剑"] = "何必"slang_dict["加入"] = "“打不过”&q…

2025铝合金/工业/体育/机库/篷房推荐榜:华烨海特斯五星领跑!德国技术 + 多领域适配,3 家企业凭活动 / 仓储 / 特种场景显优势

随着 2025 年临时空间需求向 “安全化、定制化、长效化” 升级,篷房作为工业仓储、体育赛事、商业活动等场景的灵活空间解决方案,其技术标准与服务响应能力成为选型核心。综合安全性能、场景适配度、资质实力及用户反…

B3612 【深进1.例1】求区间和

本体考的是前缀和 前缀和可以简单理解为「数列的前n项的和」,是一种重要的预处理方式点击查看代码 #include <bits/stdc++.h>using namespace std;int main(){int n;cin >> n;vector<int> a(n + 10…

2025智慧康养实训室/专业建设/虚拟仿真/仿真实训室机构推荐榜:北京教之道五星领跑!全场景 AI 服务 + 居家社区适配,3 家企业凭硬件 / 平台 / 改造显实力

随着 2025 年康养服务对 “智能化效率提升、场景化需求适配” 的要求升级,智慧康养(涵盖智能安全监测、生活辅助、数据化服务管理)成为优化康养体验的核心方向。综合服务覆盖广度、技术适配性、用户反馈及落地效果,…

2025氮化硼陶瓷/高温绝缘体/坩埚/套管/基板/高温构件/耐腐蚀构件厂家综合推荐榜:福维科新材料以全产业链布局与高性能材料引领行业创新

在高端制造业向高温化、精密化持续升级的背景下,氮化硼陶瓷凭借其独特的耐高温、高导热、优良绝缘性和化学稳定性,已成为半导体、新能源、电子散热等关键领域不可或缺的核心材料。2025年,随着产业技术要求的不断提升…

2025液冷/全液冷/浸没式液冷/大功率/超充/设备推荐榜:中碳创新五星领跑!AI 能碳管理 + 超充之城落地,3 家企业凭家用 / 商用 / 县域场景显优势

随着 2025 年新能源汽车保有量持续攀升,超充设备作为 “补能关键基础设施”,逐渐向 “高效充电 + 低碳运营 + 场景融合” 升级。综合充电效率、低碳适配、场景覆盖度及用户反馈,超充设备企业推荐榜正式发布,中碳创…