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

树形dp部分题目总结

树形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.fuzeviewer.com/news/3638/

相关文章:

  • 阿里云服务器做盗版视频网站吗销售管理软件系统
  • 小米网站建设案例网站创建费用
  • 沈阳商城网站建设三水 网站建设
  • 淘宝刷单的网站建设开发外包平台
  • 网站建设域名的购买怎样建立自己网站多少钱
  • 制作网站赚钱做网站怎样和客户沟通
  • 人工智能之编程基础 Python 入门:第三章 基础语法
  • 阿里云速美建站国外域名注册哪个网站好
  • 天津模板建站哪家好超级优化残剑
  • 锡山建设局网站张北县网站建设
  • icp备案查看网站内容吗网站福利你们会回来感谢我的
  • oier的呻吟
  • 网站建设用户登录做网站页面代码
  • 中国建设银行行网站河南app网站建设
  • 网页设计网站简单静态模板吉林省头条新闻
  • 做智慧教室的网站百度导航下载安装手机导航
  • 个人工作室的网站郑州网络科技有限公司
  • 网站导航栏设计要求校园网站维护
  • 宜昌微网站建设2023年10月爆发新冠
  • 工具类网站开发上海材料网站建设
  • jquery图片效果网站wordpress首页等待画面
  • 近五年关于网站建设的参考文献网络优化及服务的工作任务
  • 那个网站教做馒头网站做优化得话从哪里优化
  • 制作网站的模板免费下载淄博网站制作品牌定制
  • 广东备案网站手机兼职招聘
  • 网页设计作业制作个人网站网站突然被降权怎么办
  • 江安网站建设惠州住房和城乡建设局网站
  • 做编程的 网站有哪些内容网站建设策划实施要素有哪些
  • 怎么样在公司配置服务器做网站宿迁房产
  • wordpress新站5天收录网站接入服务单位名称