将$E_{i}$从小到大排序(显然不会相同),假设$E_{p_{i}}$为从小到大第$i$小

此时,必然有$E_{p_{1}}=1$,否则可以将$E_{p_{i}}$都减去$E_{p_{1}}-1$,之后即需要最小化$E_{p_{n}}$

当$p_{i}$确定后,题目中第2个条件即可变为$\forall 1\le i<j\le n,E_{p_{j}}-E_{p_{i}}\ge dist(p_{i},p_{j})$

取$j=i+1$时,即可推出$\forall 1\le i<n,E_{p_{i+1}}-E_{p_{i}}\ge dist(p_{i},p_{i+1})$

另一方面,此时即有$E_{p_{j}}-E_{p_{i}}=\sum_{k=i}^{j-1}E_{p_{k+1}}-E_{p_{k}}\ge \sum_{k=i}^{j-1}dist(p_{k},p_{k+1})\ge dist(p_{i},p_{j})$

(关于最后一个不等号,根据$dist(x,y)\le dist(x,z)+dist(z,y)$即可得到)

换言之,题目中第2个条件等价于$j=i+1$时的条件,那么$E_{p_{n}}$最小值即为$\sum_{i=1}^{n-1}dist(p_{i},p_{i+1})+1$

现在,问题即变为确定$p_{i}$,以最小化$E_{p_{n}}$(也即$\sum_{i=1}^{n-1}dist(p_{i},p_{i+1})+1$)

考虑将其补上$dist(p_{1},p_{n})$,此时考虑每一条边对答案的贡献,至少为2,且通过令$p_{i}$为dfs序来构造,可取到此下限,即和为$2(n-1)+1$

令$p_{1}$和$p_{n}$为树直径的两个端点,并以$p_{1}$为根优先搜索不包含$p_{n}$的子树即可构造出对应dfs序,令$d$为直径长度,则最终$E_{p_{n}}$即为$2(n-1)+1-d$

另外求$E_{i}$不需要求lca来求$dist(p_{i},p_{i+1})$,由于$\sum_{i=1}^{n-1}dist(p_{i},p_{i+1})$是$o(n)$的,直接在树上暴力移动,并判定其是否是后代即可

另外,题解中还提到了如何$o(n)$实现spj,只需要用桶排来对$p_{i}$排序,并以此判定相邻两者插值是否恰好为其距离即可

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 struct Edge{
5 int nex,to;
6 }edge[N<<1];
7 int E,n,x,y,head[N],dfn[N],f[N],sz[N],dep[N],P[N],ans[N];
8 bool check(int x,int y){
9 return (dfn[x]<=dfn[y])&&(dfn[y]<dfn[x]+sz[x]);
10 }
11 void add(int x,int y){
12 edge[E].nex=head[x];
13 edge[E].to=y;
14 head[x]=E++;
15 }
16 int dis(int x,int y){
17 int ans=0;
18 while (!check(x,y)){
19 ans++;
20 x=f[x];
21 }
22 while (!check(y,x)){
23 ans++;
24 y=f[y];
25 }
26 return ans;
27 }
28 void dfs(int k,int fa,int s){
29 dfn[k]=++dfn[0];
30 f[k]=fa;
31 sz[k]=1;
32 dep[k]=s;
33 for(int i=head[k];i!=-1;i=edge[i].nex)
34 if (edge[i].to!=fa){
35 dfs(edge[i].to,k,s+1);
36 sz[k]+=sz[edge[i].to];
37 }
38 }
39 void construct(int k,int fa){
40 P[++P[0]]=k;
41 for(int i=head[k];i!=-1;i=edge[i].nex)
42 if ((edge[i].to!=fa)&&(!check(edge[i].to,y)))construct(edge[i].to,k);
43 for(int i=head[k];i!=-1;i=edge[i].nex)
44 if ((edge[i].to!=fa)&&(check(edge[i].to,y)))construct(edge[i].to,k);
45 }
46 int main(){
47 scanf("%d",&n);
48 memset(head,-1,sizeof(head));
49 for(int i=1;i<n;i++){
50 scanf("%d%d",&x,&y);
51 add(x,y);
52 add(y,x);
53 }
54 dfs(1,0,0);
55 x=y=1;
56 for(int i=2;i<=n;i++)
57 if (dep[x]<dep[i])x=i;
58 dfs(x,0,0);
59 for(int i=2;i<=n;i++)
60 if (dep[y]<dep[i])y=i;
61 construct(x,0);
62 ans[P[1]]=1;
63 for(int i=1;i<n;i++)ans[P[i+1]]=ans[P[i]]+dis(P[i],P[i+1]);
64 for(int i=1;i<=n;i++)printf("%d ",ans[i]);
65 }

[ARC117D]Miracle Tree的更多相关文章

  1. Atcoder Regular Contest 117 D - Miracle Tree(分析性质+构造)

    Atcoder 题面传送门 笑死,阴间语文作业到现在还没写完,为了在这个点保持精神,我只好来颓篇题解辣 我们考虑探究一下怎么最小化 \(\max\limits_{i=1}^nE_i\),我们假设 \( ...

  2. QTREE5 - Query on a tree V——LCT

    QTREE5 - Query on a tree V 动态点分治和动态边分治用Qtree4的做法即可. LCT: 换根后,求子树最浅的白点深度. 但是也可以不换根.类似平常换根的往上g,往下f的拼凑 ...

  3. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 好像这个题只能Dsu On Tree? 有根树点分治 统计子树过x的 ...

  4. AT3912 Antennas on Tree

    AT3912 Antennas on Tree %%zzt 只能考虑性质了. 把最后选择的k个点的连通块求出来,连通块内部的点表示都是互异的 连通块外部的点只能形成若干条链,并且这k个点的每一个最多与 ...

  5. CF1055F Tree and XOR

    CF1055F Tree and XOR 就是选择两个数找第k大对儿 第k大?二分+trie上验证 O(nlognlogn) 直接按位贪心 维护可能的决策点(a,b)表示可能答案的对儿在a和b的子树中 ...

  6. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  7. SAP CRM 树视图(TREE VIEW)

    树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...

  8. 无限分级和tree结构数据增删改【提供Demo下载】

    无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...

  9. 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...

随机推荐

  1. MySQL MHA 运行状态监控

    一 项目描述 1.1 背景 MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了 automating master failover 功能.MHA ...

  2. python日志配置及调用

    0.日志基础操作 import logging logging.basicConfig( #1.日志输出的位置,终端和文件 filename='access.log', #,不指定默认打到终端上 #2 ...

  3. mybatis 操作数据库(05)

    类型转换.动态排序,查询接口与mapper对应关系说明及其注意事项 一.MyBatis 自带写常见类型转换器.例如:java 类中 String 对应 mySQL中的varchar 二.自定义类型转换 ...

  4. iOS平台 | 快速集成华为AGC认证服务

    介绍 如何让用户根据已有的账号来进行登录注册呢?在应用中集成华为AGC认证服务SDK来轻松快速地实现这个功能. 本篇内容根据官网文档指导集成过程总结完成,关于集成步骤,官网的资料写的有点多,现在我总结 ...

  5. Java 是编译型语言还是解释型语言?

    Java首先由编译器编译成.class类型的文件,这个是java自己类型的文件.然后在通过虚拟机(JVM)从.class文件中读一行解释执行一行.因此Java是一种半编译半解释的语言,理解这种意思即可 ...

  6. [Beta]the Agiles Scrum Meeting 4

    会议时间:2020.5.15 21:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 yjy 增加教学计划面板,修复bug tq 实现查看.删除测试点功能 wjx 实现批量创建结对项目功能 ...

  7. Pandas核心用法

    目录 Numpy和Pandas Numpy科学计算 Pandas数据分析 安装jupyter notebook Numpy语法 创建和基本使用 切片索引 布尔索引 对位运算 矩阵的乘除 其他方法 Pa ...

  8. 色彩滤镜矩阵(Color Filter Array)

    数码相机上的每个象素都带有一个光感应器,用以测量光线的明亮程度.由于光电二极管是只支持单颜色的装置,它不能区别不同波长的光线.因此,数码相机工程师在相机感应器的上部装上了一套镶嵌式的颜色滤镜,一个颜色 ...

  9. 上拉电阻大小对i2c总线的影响

    漏极开路上拉电阻取值为何不能很大或很小? 如果上拉电阻值过小,Vcc灌入端口的电流(Ic)将较大,这样会导致MOS管V2(三极管)不完全导通(Ib*β<Ic),有饱和状态变成放大状态,这样端口输 ...

  10. 如何清理history

    工作中,需要清理history 清理当前会话历史命令    history -c 清理当前用户所有历史命令     echo > .bash_history     #在用户主目录执行此操作