题意:一棵点数为n的树,每个节点有点权,要求在树中中找到一个最小的x,使得存在一个点满足max(该点点权,该点相邻的点的点权+1,其他点的点权+2)=x

分析:首先要能把题目转化为上述题意

  首先题目让你选取一个点为根节点,

  然后断掉这个点

  让相邻的点与二次相邻的点的点权+1

  然后剩下每次只能断掉与该点相邻的点,

  断掉后处理与根节点断掉的处理一致

  显然,对于任何一个根节点的儿子来说,他的权值一定只被+1

  而对于其他节点来说,他的权值一定在他父亲断掉时和爷爷断掉时分别+1,也就是+2

那么我们现在转化完题目,现在剩下的题目其实就是个类似模拟的东西,不过还是有可聊之处的

  首先,如果只有一个拥有最大点权的点,令该最大点权为maxa

    那么显然一定要以这个节点为根节点,

    因为如果不以该节点为根节点,那么最终结果至少为maxa+1

    而如果以该节点为根节点,显然当点权为maxa-1的点位于根节点相邻以外的节点时,会使结果变成maxa+1,而且这是最坏情况

    最坏情况与最好情况相同,显然要选该节点为根节点

  那么求最终结果只需要dfs一下,将根节点的儿子+1,其余节点+2,最后在所有节点中求最大值即可

  然后,如果有多个拥有最大点权的点呢?

  很容易得到的不一定非要将根节点设在最大点权的点上,比如

  

  加粗的节点是最大点权的点

  显然将根节点设在1一定比将根节点设在2或4更优

  那么也很容易得到,当所有的最大点权的点都连在同一个点上时,才会出现maxa+1这种结果,比如

  

  

  而如果不连在同一个节点上,则结果就是maxa+2,如

  那么我们如何判断所有的最大点权的点是否连在同一个节点上呢?

  最简单的方法肯定是直接用floyd之类的方法求出任意两个最大点权的点之间的距离

  如果出现有一个距离>2,那么这两个点显然就不可能连在同一个节点上或相邻

  如果没有出现,那么显然他们一定是连在同一个节点上的

  那么这样的方法显然是超时的,

  那么我们能不能省略几次呢?

  首先如果我们只以其中任意一个节点为根,

  用dfs求出其他节点到该节点的距离,

  然后再判断是否存在>2的,

  显然并不能得到我们想要的结果,比如

  

  如果我选的是节点2,显然与正确答案不符

  那么如果我任选两个可以吗

  答案也是不行的,不过这个可能有点难想,比如这个

  

  如果我选的是1,4,那么得到的结果就与答案不符

  那么如果我选3个呢?

  好像没找到反例,那怎么证明一定符合我们的要求呢?

    首先,如果存在3个节点没出现距离大于二,那么他们两两之间距离一定小于等于2

    那么他们只有两种可能

    第一种是

    第二种是

    对于第一种来说,其实只需要两个节点保证没有出现距离大于2的节点就可以得到结果

      考虑极端的等于2的情况,我对于任意一个根节点一定满足这个图

      

      而此时有两个节点满足该情况,如果出现5,6这种情况,显然就不可能出现两个节点满足该情况

      所以也就是说只能出现这种情况

      

      显然这种情况一定是成立的

    那么对于第二种情况来说,

      

      4会排除2子树中的干扰,2会排除4子树中的干扰,所以剩余的节点只能为1节点的儿子,从而得证

    理一下,刚才较为冗长的证明证明了只需要任选三个最大权值节点dfs即可,这三个节点若找到一个与他们距离>2的最大权值节点,那么最终结果就是maxa+2,否则就是maxa+1

代码:

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std; const int maxn=3e5+;
const int inf=1e9+; struct Node
{
int to,next;
}e[maxn<<];
int head[maxn];
int len[maxn];
int a[maxn];
vector<int> q;
int cnt; void add(int x,int y)
{
e[++cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt;
} void dfs(int x,int fa)
{
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
if(fa==-) a[v]++;
else a[v]+=;
dfs(v,x);
}
}
} void dfslen(int x,int fa)
{
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
len[v]=len[x]+;
dfslen(v,x);
}
}
} int chuli()
{
for(int i=;i<min((int)q.size(),);i++)
{
len[q[i]]=;
dfslen(q[i],-);
for(int j=;j<q.size();j++) if(len[q[j]]>) return ;
}
return ;
} int main()
{
int n,x,y;
scanf("%d",&n);
int maxa=-inf;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]>maxa) maxa=a[i],q.clear(),q.push_back(i);
else if(a[i]==maxa) q.push_back(i);
}
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
if(q.size()==)
{
dfs(q[],-);
for(int i=;i<=n;i++) maxa=max(maxa,a[i]);
printf("%d",maxa);
}
else printf("%d",maxa+chuli());
return ;
}

题目分享E 二代目的更多相关文章

  1. 题目分享D 二代目

    题意:给定一个T条边的无向图,求S到E恰好经过N条边的最短路径 T≤100 N≤1000000 分析:(据说好像假期学长讲过) 首先很容易想到的是dp[i][j][k]表示从i到j经过k条边的最短路径 ...

  2. 题目分享C 二代目

    题意:一个数列是由 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6.....组成,也就是1-1,1-2,1-3......并且如果遇到多位数也要拆成数字比如1-10 ...

  3. 题目分享H 二代目

    题意:有m个限制,每个限制l1,r1,l2,r2四个数,限制了一个长度为n的数第l1到r1位要与第l2到r2相同,保证r1-l1=r2-l2,求在限制下一共有多少种数 分析: 暴力的话肯定是从l1-r ...

  4. 题目分享G 二代目

    题意:有n组数,每组包含两个数,问在每组只能取一个的前提下能组成的最长的从1开始的连续自然数有几个? 分析:刚学了差分约束系统,很容易往转换成图的方向去想 将他读入的这n组数当成边读入 很容易会得到一 ...

  5. 题目分享F 二代目

    题意:T个点R种双向边,P种单向边,求点S到每个点的最短距离 分析:(这再看不出来是spfa就该**了) 首先,这题能否用spfa就看他是否有负环呗,显然,双向边的权值非负,单向边还有个啥政策,总之显 ...

  6. 2019年腾讯PHP程序员面试题目分享

    有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群​jq.qq.com 1. php 的垃圾回收机制 PHP 可以自动进行内存管理,清除 ...

  7. 20190924-LeetCode解数独题目分享

    解决数独 题目描述 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以 ...

  8. 题目分享X

    题意:一张票有n位数,如果这张票的前一半数字的和等于后一半数字的和(n一定是偶数),就称这张票为快乐票.有些数被擦除了,标记为’?’(’?‘的个数也是偶数),现在Monocarp 和 Bicarp 进 ...

  9. 题目分享V

    题意:现在两个人做游戏,每个人刚开始都是数字1,谁赢了就能乘以k^2,输的乘以k(k可以是任意整数,每次不一定相同)现在给你最终这两个人的得分,让你判断是否有这个可能,有可能的话Yes,否则No. 分 ...

随机推荐

  1. coding++:java 线程池概述

    前言: 1):创建一个可缓存线程池 2):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程. 3):创建一个定长线程池,支持定时及周期性任务执行 4):创建一个单线程化的线程池,它只 ...

  2. html字体大小与颜色设置

    代码架构:<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> //浏览器识 ...

  3. hadoop(五)scp命令copy文件和配置(完全分布式准备二)|7

    机器的克隆参考centos7克隆ip|机器名|映射关系|别名配置(hadoop完全分布式准备一) 那么问题来了,如果我们有30台机器,之间可以互相访问,那我们如何快速安装配置环境如jdk hadoop ...

  4. AD颗粒化密码规则策略

    我们在第一次设定密码规则的时候,通常会在根节点或者默认组策略中设置 如果,我们在后期运维过程中,有一些特殊用户需要设置额外的密码策略,我们要如何操作呢? 可能,有些同学会在这些特殊用户对应的OU下在创 ...

  5. coding++:Spring 中的 AOP 原理

    为什么使用 AOP 如下场景: 现在有一个情景: 我们要把大象放进冰箱,步骤为:打开冰箱->放入大象->关闭冰箱 如果再把大象拿出来,步骤为:打开冰箱->拿出大象->关闭冰箱 ...

  6. [算法]Huffman树(哈夫曼树)

    目录 一.关于Huffman树 二.具体实现 例1:P1090 合并果子 例2:P2168 [NOI2015]荷马史诗 一.关于Huffman树 Huffman树(哈夫曼树)可以解决下述问题: 一颗\ ...

  7. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十一)之Holding Your Objects

    To solve the general programming problem, you need to create any number of objects, anytime, anywher ...

  8. Python 输出漂亮的表格的5个案例,实用方便

    文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:程序IT圈 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行 ...

  9. abp(net core)+easyui+efcore实现仓储管理系统——入库管理之九(四十五)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  10. C# 基础知识系列-13 常见类库(三)

    0. 前言 在<C# 基础知识系列- 13 常见类库(二)>中,我们介绍了一下DateTime和TimeSpan这两个结构体的内容,也就是C#中日期时间的简单操作.本篇将介绍Guid和Nu ...