51nod1803 森林直径
[传送门]
考虑计算直径的 dp 方法。
$d[u]$ 表示以 $u$ 为根的子树能 $u$ 能走到的最远距离
$dp[u]$ 表示以 $u$ 为根的子树的直径
那么每次dfs一个子节点后
$dp[u] = max(d[u] + d[v] + 1, dp[u])$
$d[u] = max(d[v] + 1, d[u])$
注意顺序一反就错了。
这里并没有考虑到 $u$ 是某个节点的儿子是,路径可以往父节点走的情况,但是这是对的。
因为如果这种情况存在,那么我们在递归回父节点是就可以更新到。所以直径取最后 dp 数组的最大值是对的。
回到这个题,因为数据的生成方式,树高不超过 $log n$,并且第 $i$ 条边一定有 第 $i + 1$个节点。
如果从 $[x, n - 1]$ 这棵树已经建好了,那么加入第 $x - 1$ 条边就是把 $p[x - 1]$ 和 $x$ 这两个节点形成的连通块进行合并。
深度不超过 $log n$,那么可以暴力一点。
将询问离线。按 $r$ 从大到小排序,考虑倒序建这棵树。
$f[u][i]$ 表示以 $u$ 为根的子树内 $u$ 能到达的最远距离为 $i$ 时 $r$ 的最小值。即在 $[l, f[u][i]]$ $u$ 能往下走 $i$ 步。
$g[i]$ 表示树的直径至少为 $i$ 时 最小的 $r$。即在 $[l, g[i]]$ 树的直径至少为 $i$。
倒序加入一条边,相当于两棵树合并,那么就先更新 $g$ 数组,具体更新方式如 $dp$ 的更新方式,分别枚举高度进行合并。
$g[i + j + 1] = min(g[i + j + 1], max(f[u][i], f[v][i], v - 1))$ $v-1$ 即为当前加入的边。
在更新 $u$,即 $u$ 为 $v$ 的父亲。
$f[u][i] = min(f[u][i], max(f[v][i - 1], v - 1))$
求答案就枚举高度看 $g$ 数组是否小于当前 $r$
#include <bits/stdc++.h>
using namespace std; const int N = 5e5 + ;
const int dep = ; struct In {
int l, r;
bool operator < (const In &rhs) const {
if (l == rhs.l) return r > rhs.r;
return l > rhs.l;
}
} que[N]; int f[N][dep + ];
int g[dep * ];
int p[N], n; void add(int u, int v) {
for (int i = ; i < dep; i++) if (f[u][i] < n)
for (int j = ; j < dep; j++)
g[i + j + ] = min(g[i + j + ], max(f[u][i], max(f[v][j], v - )));
for (int i = ; i < dep; i++)
f[u][i] = min(f[u][i], max(f[v][i - ], v - ));
} int main() {
scanf("%d", &n);
memset(f, 0x3f, sizeof(f));
for (int i = , x; i < n; i++)
scanf("%d%d", p + i, &x), f[i][] = ;
f[n][] = ;
memset(g, 0x3f, sizeof(g));
int q;
scanf("%d", &q);
for (int i = ; i <= q; i++)
scanf("%d%d", &que[i].l, &que[i].r);
sort(que + , que + + q);
int now = n - ;
int ans = ;
for (int i = ; i <= q; i++) {
while (now && now >= que[i].l) {
add(p[now], now + );
now--;
}
for (int k = dep * ; k >= ; k--) {
if (g[k] <= que[i].r) {
ans += k;
break;
}
}
}
printf("%d\n", ans);
return ;
}
51nod1803 森林直径的更多相关文章
- BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
- 2021.08.09 P7238 迷失森林(树的直径)
2021.08.09 P7238 迷失森林(树的直径) P7238 「DCOI」迷失森林 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.树的直径两种求法:两次dfs.树 ...
- 『Island 基环树直径』
Island(IOI 2008) Description 你准备浏览一个公园,该公园由 N 个岛屿组成,当地管理部门从每个岛屿 i 出发向另外一个岛屿建了一座长度为 L_i 的桥,不过桥是可以双向行走 ...
- 【FJWC 2019】 森林
[FJWC 2019] 森林 样例输入 0 5 1 0 0 2 样例输出 1 2 3 3 我们发现,答案就是直径加上直径上某个点出发,不经过其他直径上的点的最长链.这里的直径可以是任意一条直径. 首先 ...
- 51Nod1367 完美森林 贪心
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1367.html 题目传送门 - 51Nod1367 题意 有一棵N个点的树,树中节点标号依次为0,1 ...
- D4 树的直径、重心以及基环树
第一题第二题鉴上我前几篇博客poj1985 poj1849:https://www.cnblogs.com/Tyouchie/p/10384379.html 第三题:数的重心:poj1655 来自sj ...
- 求树的直径+并查集(bfs,dfs都可以)hdu4514
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...
- 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...
- Codeforces 455C Civilization:树的直径 + 并查集【合并树后直径最小】
题目链接:http://codeforces.com/problemset/problem/455/C 题意: 给你一个森林,n个点,m条边. 然后有t个操作.共有两种操作: (1)1 x: 输出节点 ...
随机推荐
- 安装Windows10出现无法识别磁盘时的解决方案
由于前些日子对deepin系统比较感兴趣,一时兴起把备用机刷成了deepin,奈何还是过分依赖windows下的软件,又不得不再刷回Win10. 但由于Linux支持的磁盘格式与Windows不同,在 ...
- .NET CORE 中的缓存使用
Net Framewoke的缓存 1.1 System.Web.Caching System.Web.Caching应该是我们最熟悉的缓存类库了,做ASP.NET开发时用到缓存基本都是使用的这个缓存组 ...
- 第三章 Maven构建 Java Spring Boot Web项目
3.1 认识Srping Boot Spring Boot是一个框架,是一种全新的编程规范,它的产生简化了对框架的使用,简化了Spring众多的框架中大量的繁琐的配置文件,所以说Spring Bo ...
- react,react-router,redux+react-redux 构建一个React Demo
创建初始化应用 加速我们的npm. npm install -g cnpm --registry=https://registry.npm.taobao.org 利用create-react-app ...
- RocketMQ原理及源码解析
RocketMQ原理深入: 一.定义: RocketMQ是一款分布式.队列模型的消息中间件,有以下部分组成: 1.NameServer: 一个几乎无状态的节点,可集群部署,节点之间无任何信息同步 2. ...
- EnumSet详细讲解
https://blog.csdn.net/tugangkai/article/details/89631886 之前介绍的Set接口的实现类HashSet/TreeSet,它们内部都是用对应的Has ...
- 另类WebShell监测机制--基于auditd
鸣 谢 VSRC感谢业界小伙伴——老陈投稿精品原创类文章.VSRC欢迎精品原创类文章投稿,优秀文章一旦采纳发布,将有好礼相送,我们为您准备的丰富奖品包括但不仅限于:MacbookAir.VSRC定制 ...
- mysql.cnf配置文件详解
参数详解 [client] #客户端设置,即客户端默认的连接参数port = 3307 #默认连接端口socket = /data/mysqldata/3307/mysql.sock #用于本地连 ...
- CDA数据分析【第二章:数据收集与导入】
一.概述 数据是对我们所研究现象的属性和特征的具体描述,在分析数据前必须要做的工作就是收集数据.按照存储形式可以将数据划分为结构化数据.非结构化数据和半结构化数据. 1.结构化数据 能够用数据或统一的 ...
- redis-5.0.5安装(linux centos)
下载 cd /data wget http://download.redis.io/releases/redis-5.0.5.tar.gz 历史版本库地址 http://download.redis. ...