题意:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

分析:这可以说是换根法的裸题吧

首先考虑对一个给定的根如何计算,这应该是最简单的那种树形dp吧甚至可能都不算dp(好像还真不算dp)

dp[i]表示i点所有孩子(包括自己)的深度之和

deep[i]表示i点的深度

dp[x]=sum(dp[v]) +deep[x]    v|v是x的子节点

用一遍dfs即可搞定dp[1]-dp[n]

当然这里用谁为根都可以,用1就行

比如我们现在已经处理出dp[1]-dp[n]的值

因为如果我们用2做根的时候,虽然发现所有人的dp值都改变了(每个人深度都改变了),这与我们之前学习的换根法可能会有一点区别

但能发现的是,我们当前根节点的儿子想上位所需要改变的东西(dp值)其实O(1)就可以解决,或者说有规律可言,所以我们可以用换根法

那么怎么改变?或者说有什么规律?

首先要先记住一点的还是那个状态转移方程      dp[x]=sum(dp[v]) +deep[x]    v|v是x的子节点

再考虑这里面中每一项都怎么变的

就拿原来根是1换成2来说

首先,1除了2以外的子树的所有节点包括1在内(1,3,6,7,8),深度都+1

而2的子树包括2在内(2,3,5),深度都-1

然后好像就没啥别的变化了

那么再看dp值是怎么变的

首先dp[1]的值要先减去dp[2]的值,得到1除了2以外的子树包括1在内的深度之和,而得到这个之和dp[1]还要加上这些节点的个数,因为每个节点的深度都加一嘛

用son[i]表示i的子节点个数(包括自己)

也就是说dp[1]=dp[1]-dp[2]+(son[1]-son[2])(这是1除了子树2以外的节点数目)

而dp[2]是要先减去节点个数,再加上当前1的dp值(dp[1]修改后的值),因为此时1已经是2的儿子了

dp[2]=dp[2]-son[2]+dp[1]

注意这里是有先后顺序的

当然我们在第一遍dfs的时候要多算一遍son[i]

还有一点细节

在我们换根的时候要记得dfs完这个子树要还原成原来的样子再dfs下一个子树,而我们在dfs子树的时候其实与根节点是没有关系的,dfs只能往下搜嘛

也就是说我们在交换1和2的时候dp[1]的值不需要修改,所以我直接把dp[1]的式子带入到dp[2]的式子里就行了,也就是

dp[2]=dp[2]-son[2]+dp[1]-dp[2]+son[1]=dp[1]+son[1]-son[2]*2

最后把以所有点为根的结果取个最值就行了

代码:

 #include<cstdio>
#include<algorithm>
#include<vector>
using namespace std; #define ll long long const int maxn=1e6+; struct Node
{
int to,next;
}e[maxn<<];
int head[maxn];
ll dp[maxn];
int son[maxn];
int cnt,k,n;
ll maxans; void add(int x,int y)
{
e[++cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt;
} void dfs1(int x,int fa,int now)
{
dp[x]=(ll)now,son[x]=;
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
dfs1(v,x,now+);
dp[x]+=dp[v];
son[x]+=son[v];
}
}
} void dfs2(int x,int fa)
{
if(dp[x]>maxans||dp[x]==maxans&&x<k) k=x,maxans=dp[x];
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
ll now=dp[x]-dp[v]+(ll)son[x]-(ll)son[v]*;//这里是为了方便还原,下面用的+=和-=
int nowv=son[v];
son[v]=son[x];
dp[v]+=now;
dfs2(v,x);
dp[v]-=now;
son[v]=nowv;
}
}
} int main()
{
int n,x,y;
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs1(,-,);dfs2(,-);
printf("%d",k);
return ;
}

题目分享Q的更多相关文章

  1. 题目分享E 二代目

    题意:一棵点数为n的树,每个节点有点权,要求在树中中找到一个最小的x,使得存在一个点满足max(该点点权,该点相邻的点的点权+1,其他点的点权+2)=x 分析:首先要能把题目转化为上述题意 首先题目让 ...

  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. 题目分享X

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

  4. 题目分享V

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

  5. 题目分享T

    题意:蛐蛐国里现在共有n只蚯蚓(n为正整数).每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n),并保证所有的长度都是非负整数(即:可 能存在长度为0的蚯蚓).每一秒,神刀手会 ...

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

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

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

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

  8. 题目分享F 二代目

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

  9. 题目分享D 二代目

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

随机推荐

  1. web系统安全运营之基础- 基于DFA算法的高性能的敏感词,脏词的检测过滤算法类(c#).

    [概述]做好一个web系统的安全运维,除了常规的防注入,防入侵等,还有一个检测并过滤敏感词,脏词..  这件事做得不好,轻则导致一场投诉或纠纷,重则导致产品被勒令关闭停运. 废话少说,先看下代码,可以 ...

  2. Python操作rabbitmq系列(一)

    从本文开始,接下来的内容,我们将讨论rabbitmq的相关功能.我的这些文章,最终是要实现一个项目(具体是什么暂不透露).前面每一篇,都是在为这个系统做准备.rabbitmq,是我们这个项目的关键部分 ...

  3. mysql添加,授权,删除用户以及连接数据库Can't connect to MySQL server on '192.168.31.106' (113)错误排查

    centos7下面操作mysql添加,授权,删除用户 添加用户 以root用户登录数据库,运行以下命令: create user test identified by '; 上面创建了用户test,密 ...

  4. CORS漏洞的学习与分析

    同源策略 同源策略(Same origin policy)是一种约定,一种非常重要的安全措施,也是最基本的安全功能,它禁止了来自不同源的脚本对当前页面的读取或修改,从而限制了跨域访问甚至修改资源,防止 ...

  5. PHP 5.6连接MySQL 8.0版本遇到的坑

    一.数据库失败Warning: mysqli_connect(): The server requested authentication method unknown to t... <?ph ...

  6. AJ学IOS(34)UI之Quartz2D画画板的实现

    AJ分享,必须精品 效果: 实现过程: 首先用storyboard搭建界面,没有什么好说的. 然后就是注意的功能了,这里用了触摸事件来搭配Quartz2D的路径来画画. 思路就是把路径放到数组中 @p ...

  7. L18 批量归一化和残差网络

    批量归一化(BatchNormalization) 对输入的标准化(浅层模型) 处理后的任意一个特征在数据集中所有样本上的均值为0.标准差为1. 标准化处理输入数据使各个特征的分布相近 批量归一化(深 ...

  8. Python - 调用接口合并文件夹下多个Excel表

    在工作中经常遇到需要打开许多个excel表格,然后合并的需求,合并的同时要求格式必须原汁原味的保留.利用VBA代码可以比较轻松的解决,现在我们来看Python中如何实现. 上代码: from open ...

  9. 开源软件SoftEther使用

    最近在寻找比较好用的开源VPN,感觉SoftEther很符合我的需求.一方面是SoftEther属于开源软件并且一直在更新,另一方面是功能强大,好用. VPN支持路由功能和NAT功能,还支持多种类型的 ...

  10. mybatis源码学习:基于动态代理实现查询全过程

    前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...