这道题的题面有点问题,如果按照题面做,应该是A不了的,下面引用一下评论里@REM_001的翻译

一棵n个节点的树,行动中心S从1->N。从S出发前往任意一个未标记到的点(沿树上两点的唯一路径走),标记该节点,然后返回S。相邻两次行动所经过的道路不允许有重复,最后一次标记后不需要返回,求路程总和的最小值。

第i行输出行动中心为i时的答案,如果不可能则输出-1

这种翻译好像跟题面没什么区别啊。

别着急,下面就知道区别在哪里了。

题面要求,相邻两次到达的点不能有公共边,说白了就是以 \(S\) 为根的树每次取的点不能来自同一颗 \(S\) 的子节点的子树。那么再简化一下,就是 \(S\) 的子节点的子树节点数最大不能超过\(n/2\)。为什么呢?如果超过一半了,肯定会出现相邻啊。

那么这里就出现了一个临界值。\(n-1\)个点排成的队列,如果\(n\)是偶数,比如说是\(4\)。那么最大的子节点的子树大小最大就是\(2\)这个时候,队列的最后一个点就被确定一定是这个大小为\(2\)的子树上的点。意识到什么不对的地方了吗?

如果按照题面翻译的那样,我们是不需要考虑这种情况的,但是正确的题面可是要考虑这个临界值的啊。这也就是有的人怎么改都A不了的原因了。题面都是错的,怎么可能写对嘛。

上面我们讲了怎么判定,那么怎么求最大的子节点的子树大小呢?设 \(s[u]\) 表示以\(u\)为根的子树大小,我们先随便选一个点为根节点,然后dfs一遍求出\(s[u]\),此时的\(s[u]\)表示的是以\(u\)的父节点为根节点时,以\(u\)为根的子树大小。当以\(u\)的子节点为根节点时,以\(u\)为根的子树大小为\(n-s[u]+1\),这里很好理解,就不说为什么了。

能够判定了,我们还需要求距离和,还有最大距离。

我们定义\(w[u][0]\)表示以\(u\)为根节点的子树上的点到\(u\)的距离和,\(w[u][1]\)表示不在以\(u\)为根节点的子树上的点到\(u\)的距离和,跑两遍dfs就可以求出。然后就是求距离,这个很简单,我们在下面的程序里说

下放程序

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc getchar
#define maxn 1000005
using namespace std; inline ll read(){
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}int n;ll ans; struct ahaha{
int to,next;
}e[maxn<<1];int tot,head[maxn];
inline void add(int u,int v){
e[tot].to=v,e[tot].next=head[u];head[u]=tot++;
} int f[maxn],l[maxn],s[maxn];ll w[maxn][2]; //f记录父子关系,l记录最远距离,s记录子树大小,w[0]表示下方的点的距离和,w[1]表示上方的点的距离和
int p[maxn],d1[maxn],d[maxn][2]; //p表示下方距离的最大值经过哪一个子节点,d1表示下方距离次大值,d[0]表示下方距离最大值,d[1]表示上方距离最大值
void dfs(int u,int fa){s[u]=1;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;if(v==fa)continue;
dfs(v,u);f[v]=u;s[u]+=s[v]; //先递归,再处理 s的处理也很常见
w[u][0]+=w[v][0]+s[v]; //加上s[v]是加上uv相连的这条边的贡献
if(d[v][0]+1<=d1[u])continue; //如果v下方最大值+1还不如u下方次大值大,我们就可以直接走了
if(d[v][0]+1>=d[u][0]){ //如果大于等于最大值,更新次大值,更新最大值,更新最大值来源。为什么等于也可以大家可以自己想一想,很简单
d1[u]=d[u][0];
d[u][0]=d[v][0]+1,p[u]=v;
continue;
}
d1[u]=d[v][0]+1; //剩下的情况就是 d1[u]<d[v][0]+1<d[u][0] 所以更新次大值
}
}
void dfs1(int u,int fa){
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;if(v==fa)continue;
if(v==p[u])d[v][1]=max(d1[u],d[u][1])+1; //如果是父节点的最大值来源,那么用次大值更新
else d[v][1]=max(d[u][0],d[u][1])+1; //反之,用最大值更新
w[v][1]=(ll)n-s[v]+w[u][1]+w[u][0]-w[v][0]-s[v]; //n-s[v]表示uv相连的边的贡献,w[u][0]-w[v][0]-s[v]表示父节点的其他子节点的贡献
dfs1(v,u); //先处理,再递归
}
} int main(){memset(head,-1,sizeof head);
n=read();
if(n==1){ //对于只有一个节点的树我们直接特判
puts("0");
return 0;
}
for(int i=1;i<n;++i){ //读入所有边
int u=read(),v=read();
add(u,v);add(v,u);
}
dfs(1,-1);dfs1(1,-1); //第一遍dfs自下而上处理,第二遍自上而下
for(int u=1;u<=n;++u){
int maxa=0,a,k;
for(int i=head[u];~i;i=e[i].next){ //求出以当前节点为根,最大的子节点的子树大小,并记录是哪个子节点
int v=e[i].to;k=f[v]==u?s[v]:n-s[u];
if(k>maxa)maxa=k,a=v;
}
if((maxa<<1)>n){ //如果超过一半,必定会相邻,输出-1
puts("-1");
continue;
}
l[u]=(maxa<<1)==n?(f[a]==u?d[a][0]+1:(max(p[a]==u?d1[a]:d[a][0],d[a][1])+1)):max(d[u][0],d[u][1]); //这一行的意思是如果不是前面提到的临界值,那么直接找最大距离即可;但是如果是临界情况,并且这个子节点依然是子节点,那么就是子节点下面的最远距离+1,如果子节点之前是父节点,那么找子节点没有经过u的最长距离+1
printf("%lld\n",(w[u][0]+w[u][1]<<1)-l[u]); //最后输出答案即可
}
return 0;
}

这道题留给我们一个教训,就是不要过分相信翻译,毕竟谁都可以递交翻译

看完不妨留个推荐?

P3525 INS-Inspection的更多相关文章

  1. 在Revit中如何显示附件模块(Add Ins) 这个命令页?zz

      分类: 概念说明 Revit Revit界面编程 Revit 二次开发入门2013-08-22 13:58 1395人阅读 评论(9) 收藏 举报 在windows 7 32-bit OS 上装了 ...

  2. HTML 文本格式化<b><big><em><i><small><strong><sub><sup><ins><del>

    <b> 标签-粗体 定义和用法: <b>标签规定粗体文本. 提示和注释 注释:根据 HTML5 规范,在没有其他合适标签更合适时,才应该把 <b> 标签作为最后的选 ...

  3. 解决author波浪线Spellchecker inspection helps locate typos and misspelling in your code, comments and literals, and fix them in one click

    自从把默认的头注释的author改成自己的名字以后越看越顺眼,但是发现名字下面一直有个波浪线,强迫症简直不能忍. 然后当你把鼠标放上去,再点击提示上的"more",会看到下面的提示 ...

  4. Inspection info: Checks Spring Boot application .properties configuration files. Highlights unresolved and deprecated configuration keys and in

    Cannot resolve class or package ‘jdbc’ less… (Ctrl+F1) Inspection info: Checks Spring Boot applicati ...

  5. windows安装oracle遇INS 30131 错误

    win2008 64位安装oracle 11.2.0.4也遇到INS 30131 错误 描述: 原因 - 无法访问临时位置. 操作 - 请确保当前用户具有访问临时位置所需的权限. 附加信息: - 所有 ...

  6. pycharm提示This inspection detects instance attribute definition outside __init__ method

    示例代码: class MiNiCarStore(CarStore): def createCar(self, typeName): self.carFactory = CarFactory() # ...

  7. pycharm提示This inspection detects any methods which may safely be made static.

    示例代码: class Car(object): # 未定义任何类属性 def move(self): # 方法会出现下划线提示This inspection detects any methods ...

  8. this inspection detects names that should resolved but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Top-level and class-level items are sup

    输入第一行代码:import logging;logging.basicConfig(level==logging.INFO) 提示:this inspection detects names tha ...

  9. 警告: No data sources are configured to run this SQL and provide advanced code assistance. Disable this inspection via problem menu (Alt+Enter). more... (Ctrl+F1) SQL dialect is not configured. Postgr

    python3出现问题: 警告: No data sources are configured to run this SQL and provide advanced code assistance ...

  10. 从模板驱动文件ins生成cls文件

    在当前目录下,启动cmd程序,输入以下指令: latex acmart.ins

随机推荐

  1. vim 入门笔记

    前言 本文的初衷 从知道 vim 开始我就有心学习并尝试过几次,每次都是暂时的心血来潮,最终全部不了了之,就连最基本的 vimtutor 我都是学个两三节就半途而废,所以这次干脆写篇文章,利用几次学习 ...

  2. 46.QT-自带库QSerialPort串口使用

    之前一章学习的是第三方库使用: 34.QT-qextserialport第三方库制作串口助手(并动态检测在线串口,附带源码) 本章来学习自带serial库 1.QSerialPortInfo QLis ...

  3. Angular框架入门

    今天简单学习了AngularJS框架,在这里我想简单的总结一下我所了解的AngularJS和一些入门案例! 首先,我们要知道什么是AngularJS? AngularJS  诞生于2009年,由Mis ...

  4. InnoDB On-Disk Structures(四)--Doublewrite Buffer (转载)

    转载.节选于 https://dev.mysql.com/doc/refman/8.0/en/innodb-doublewrite-buffer.html The doublewrite buffer ...

  5. css字体效果

    text-shadow还没有出现时,大家在网页设计中阴影一般都是用photoshop做成图片,现在有了css3可以直接使用text-shadow属性来指定阴影.这个属性可以有两个作用,产生阴影和模糊主 ...

  6. 2.华为路由交换技术_TCP/IP参考模型

    1.应用层 2.传输层(主机到主机层) 3.网络层(IPV4) ARP协议:地址解析协议 原理:源终端A想要发送信息给目的终端B,已知B的IP地址,需要获取B的MAC地址.首先它会在局域网广播,一般情 ...

  7. Unable to open debugger port: java.net.SocketException

    网上都说是tomcat端口被占用,其实不是,这是因为文件权限不够,脚本不能执行,debug当然不能接受网络连接的数据 可以在Event Log里看到 所以只需要更改文件的级别就可以了(可读可写可执行) ...

  8. 分享Java程序员50多道热门的多线程和并发面试题(答案解析)

    下面是Java程序员相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器 ...

  9. Implement Property Value Validation in Code 在代码中实现属性值验证(XPO)

    This lesson explains how to set rules for business classes and their properties. These rules are val ...

  10. CAD转DXF怎么转换?教你三种转换方法

    CAD图纸在我们日常生活中都是可见到的,因为CAD图纸文件的格式是多样的,在工作中就需要经常将CAD的格式进行转换.那CAD转DXF怎么转换呢?这个问题很多的小伙伴们都遇到过,下面小编就来教大家三种转 ...