这道题的题面有点问题,如果按照题面做,应该是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. 微信小程序模板(template)和组件的区别

    template模块主要是展示,方法需要在使用template的页面中定义,对于通用的数据,最先想到或者理应是template,但是template有个缺点,那就是只是页面效果,不会有对应的js操作. ...

  2. ImageView设置rounded corner

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/207 ImageView设置rounded corner ...

  3. find 常用命令

    系统中总会不断产生一些文件,比如日志文件,不一定会用到也不会自动删除,这时候就需要手动删除,当然也可以转存到其他目录下.不好找的时候可以用find模糊查找,加个job定时任务自动执行定期删除文件1.添 ...

  4. 使用C#面向对象实现简易计算器(简单工厂模式)

    操作流程: 1. 新建Operation类 2. 新建OperationAdd类,并继承Operation类 3. 新建OperationSub类,并继承Operation类 4. 新建Operati ...

  5. Java_可变参数类型

    Java方法中的可变参数类型,也称为不定参数类型,是一个非常重要的概念 举栗子 public class TestVarArgus { public static void dealArray(int ...

  6. A:linux基础章节导航

    本章的内容主要有: 模板机的安装 常用的小命令 find awk vim sed

  7. web安全技术--XSS和CSRF

    Xss一般是脚本代码,主要是JS的,但是也有AS和VBS的. 主要分为反射型,存储型,DOM型三个大类. 一般来讲在手工测试的时候先要考虑的地方就是哪里有输入那里有输出. 然后是进行敏感字符测试,通常 ...

  8. Ubuntu16.04 GTX750安装CUDA9.0,Pytorch,Anaconda教程

    Ubuntu16 GTX750安装CUDA9.0,Pytorch,Anaconda教程 安装前警告 不要使用Ubuntu18! 不要使用Ubuntu18! 不要使用Ubuntu18! 务必重装成Ubu ...

  9. vue介绍以及相关概念理解大全

    1.什么是vue 以官网的解释来说,vue是渐进式javascript框架.Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计 ...

  10. C# 使用NAudio合并mp3、wav音频文件

    1.什么是wav格式    WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windo ...