【NOIP2017模拟测试(10-28)】平衡树
平衡树解题报告
Description
小D最近又在种树,可是他的种树技巧还是很差,种出的树都长的歪七扭八,为了让树变得平衡一些,小D决定从树上删掉一条边,然后再加上一条边,使得到的仍然是一棵树并且这棵树的直径(树上最远两点距离)尽量小。请你求出新树的最小直径长度。每条边的长度均为1。
Input Format
第一行一个正整数n,表示树上节点个数。 第2~n行每行两个正整数x,y,表示x到y之间有一条边。
Output Format
输出一个整数,表示答案。
Sample Input
4
1 2
2 3
3 4
Sample Output
2
Hint
【数据范围】
对于数据点1~2,n<=50;
对于数据点3~4,n<=5,000;
对于数据点5~6,第i条给出的边为i到i+1的边;
对于全部数据(1~10),n<=500,000。
Solution
本题有个很直观的想法,就是枚举每一条边把它删除后再连接某对点,然后求直径
更新答案。问题是删除这条边后得到两棵树,连接这两棵树的哪对点会使直径最小呢?
(当然你也可以暴力枚举)可以证明连接两棵树的中点是最优的。
树的中心:找到一个点使得以该点为根树的深度最小(等价于找到一个点使得以该点为起点的最长的路径最短)。
证明:设我们连接的点对为(u,v)。
两棵树合并成一棵树的直径有两种情况,1.直径存在这两棵树之间,2.直径是一条经过这两棵树的路径,对于第一种情况我们无法改变(因为这两棵树已经固定了),我们能做的是让经过这两棵树的最长路径L最短,容易想到|L|其实等于以u为起点的最长路径的长度加上以v为起点的最长路径的长度加1,而使以这两个点为起点的最长路径最短的点其实就是树的中心,所以连接两棵树的中心能使情况2最小,故连接两棵树的中心是最优的。
以中点为起点的最长路径的长度=ceil(d+1) (d是树的直径)
经过以上分析,我们要做的就是时刻维护每条边删除后出现的两棵树的直径,这很容易用树形DP维护。
Code
#include<cstdio>
#include<algorithm>
#define N 500007
using namespace std;
inline int read(){
int num=0,k=1;char c=getchar();
while (c<'0'||c>'9'){if (c=='-')k=-1;c=getchar();}
while (c>='0'&&c<='9')num=(num<<1)+(num<<3)+c-48,c=getchar();
return num*k;
}
struct info{
int to,pre;
}edge[2*N];
int ans,n,size,head[N];
int fa[N],sonD[2][N],maxD[N],Down[3][N];
inline int Adl(int u,int v){
edge[++size].pre=head[u];
edge[size].to=v;
head[u]=size;
}
inline void dfs1(int k){
for (int i=head[k];i;i=edge[i].pre){
int t=edge[i].to;
if (t==fa[k]) continue;
fa[t]=k;
dfs1(t);
if (Down[0][t]+1>Down[0][k]){
Down[2][k]=Down[1][k];
Down[1][k]=Down[0][k];
Down[0][k]=Down[0][t]+1;
}
else if (Down[0][t]+1>Down[1][k])
Down[2][k]=Down[1][k],Down[1][k]=Down[0][t]+1;
else if (Down[0][t]+1>Down[2][k])
Down[2][k]=Down[0][t]+1;
if (maxD[t]>sonD[0][k]){
sonD[1][k]=sonD[0][k];
sonD[0][k]=maxD[t];
}
else if (maxD[t]>sonD[1][k])
sonD[1][k]=maxD[t];
maxD[k]=max(maxD[k],maxD[t]);
}
maxD[k]=max(maxD[k],Down[1][k]+Down[0][k]);
}
inline void dfs2(int k,int l,int D){
if (k!=1)
ans=min(ans,max((maxD[k]+1)/2+(D+1)/2+1,max(D,maxD[k])));
for (int i=head[k];i;i=edge[i].pre){
int t=edge[i].to,len,d;
if (t==fa[k]) continue;
if (Down[0][t]+1!=Down[0][k])
len=Down[0][k];
else len=Down[1][k];
if (maxD[t]!=sonD[0][k]) d=sonD[0][k];
else d=sonD[1][k];
d=max(d,max(D,len+l));
if (Down[0][t]+1==Down[0][k])
d=max(d,Down[1][k]+Down[2][k]);
else if (Down[0][t]+1==Down[1][k])
d=max(d,Down[0][k]+Down[2][k]);
else
d=max(d,Down[0][k]+Down[1][k]);
len=max(len,l)+1;
dfs2(t,len,d);
}
}
bool List;
int main(){
n=read();List=true;
for (int i=1;i<n;++i){
int u,v;
u=read(),v=read();
Adl(u,v),Adl(v,u);
if (u!=i||v!=i+1) List=false;
}
ans=n;
if (List)
for (int i=1;i<=n;++i) ans=min(ans,(n-i)/2+i);
else {
dfs1(1);
dfs2(1,0,0);
}
printf("%d",ans);
}
【NOIP2017模拟测试(10-28)】平衡树的更多相关文章
- [考试反思]0729NOIP模拟测试10
安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- NOIP模拟测试10「大佬·辣鸡·模板」
大佬 显然假期望 我奇思妙想出了一个式子$f[i]=f[i-1]+\sum\limits_{j=1}^{j<=m} C_{k \times j}^{k}\times w[j]$ 然后一想不对得容 ...
- noip模拟测试10
T1 这道题在考场上想到了二维前缀和,就是自己算前缀和的方式有点麻烦,导致花的时间较长,但还是成功搞了出来. 因为暴力计算的话需要不停枚举左上角和右下角的 i ,j, 时间复杂度为 n^4 ,我当时就 ...
- 7.29 NOIP模拟测试10 辣鸡(ljh)+模板(ac)+大佬(kat)
T1 辣鸡(ljh) 就是一道分类讨论的暴搜,外加一丢丢的减枝,然而我挂了,为啥呢,分类讨论变量名打错,大于小于号打反,能对才怪,写了sort为了调试就注释了,后来忘了解开,小减枝也没打.但是这道题做 ...
- [NOIP模拟测试10]辣鸡(ljh) 题解
首先计算块内贡献,很显然是$(x_2-x_1)*(y_2-y_1)*2$. 然后考虑矩形之间的贡献,sort一遍分类讨论$n^2$暴力即可. 注意考虑边界情况是否能多两个,以及角对角的情况. 另外,排 ...
- csp-s模拟测试10.1(b)X 国的军队,排列组合, 回文题解
题面:https://www.cnblogs.com/Juve/articles/11615883.html X 国的军队: 好像有O(T*N)的直接贪心做法 其实多带一个log的二分也可以过 先对所 ...
- 联赛模拟测试10 C. 射手座之日
题目描述 分析 方法一(线段树) 线段树维护的是以当前节点为左端点的区间的贡献 而区间的右端点则会从 \(1\) 到 \(n\) 逐渐右移 当我们把右端点从 \(i-1\) 的位置扩展到 \(i\) ...
- NOIP2017提高组模拟赛 10 (总结)
NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...
随机推荐
- 两台Windows的 IIS 应用站点 基于NLB + ARR 实现双机热备和负载
IIS负载均衡中我们使用微软的ARR,但提到网站的高可用性,ARR只能做请求入口的消息分发服务,这样如果我们的消息分发服务器给down掉啦,那么做再多的应用服务集群也都枉然. 这里我们主要针对解决这一 ...
- hexo更改主题
github+hexo搭建好个人博客之后,一般都挑选自己喜欢的主题.在这里为大家介绍一下比如何挑选主题以及如何修改主题. 主题选择: 1:知乎推荐 2:hexo官方 本地目录中打开git bash: ...
- maven 修改镜像为阿里淘宝源
修改maven根目录下的conf文件夹中的setting.xml文件,(或者当前用户目录 的 .m2 目录下的 setting.xml 文件) 内容如下: <mirrors> <mi ...
- day 06 预科
目录 if判断 if判断习题 for循环 for循环习题 微信机器人 if判断 # 一条狗朝你过来了,你会干吗? 判断: 如果狗是大长腿牵来的狗--->打招呼:如果是条疯狗,跑. # if:如果 ...
- vue---axios实现数据交互与跨域问题
1. 通过axios实现数据请求 vue.js默认没有提供ajax功能的. 所以使用vue的时候,一般都会使用axios的插件来实现ajax与后端服务器的数据交互. 注意,axios本质上就是java ...
- HDU1213通畅工程-并查集求解
并查集的经典题目. 并查集.经典题目是HDU1232通畅工程. 题目描述: 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标 ...
- mysql性能优化之服务器参数配置-内存配置
MySQL服务器参数介绍 MySQL获取配置信息路径 命令行参数 mysqld_safe --datadir=/data/sql_data 配置文件 mysqld --help --verbose | ...
- CentOS6.5_x64上简单编译配置Heartbeat3.0.4
Heartbeat 3与 2.x的最大差别在于,3 按模块把的原来2.x 拆分为多个子项目,并且提供了一个cluster-glue的组件,专用于Local ResourceManager 的管理.即h ...
- 【(图) 旅游规划 (25 分)】【Dijkstra算法】
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> us ...
- datebox设置默认时间
1. html代码: <input id="txtBeginTime" class="easyui-datebox" data-options=" ...