题意:给出一个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. 34.4 对象流 ObjectOutputStream ObjectInputStream

    * 对象操作流:可以用于读写任意类型的对象 * ObjectOutputStream * writeObject * ObjectOutputStream(OutputStream out) * Ob ...

  2. 《面试经典系列》- SpringMVC原理及工作流程

    前言 SpringMVC 作为 MVC 的开源框架,现在依旧是不少项目使用的重点框架.SpringMVC = Struts2 + Spring,SpringMVC就相当于 Struts2 + Spri ...

  3. tf.nn.depthwise_conv2d 卷积

    tf.nn.depthwise_conv2d( input, filter, strides, padding, rate=None, name=None, data_format=None ) 参数 ...

  4. Node.js 的事件循环机制

    目录 微任务 事件循环机制 setImmediate.setTimeout/setInterval 和 process.nextTick 执行时机对比 实例分析 参考 1.微任务 在谈论Node的事件 ...

  5. java网络编程socket\server\TCP笔记(转)

    java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04|  分类: Socket |  标签:java  |举报|字号 订阅     1 TCP的开销 a ...

  6. 文档根元素 "beans" 必须匹配 DOCTYPE 根 "null"

    文档根元素 "beans" 必须匹配 DOCTYPE 根 "null" (2011-11-20 21:26:41) 转载▼ 标签: 杂谈 分类: spring- ...

  7. 2019-07-31【机器学习】无监督学习之聚类 K-Means算法实例 (图像分割)

    样本: 代码: import numpy as np import PIL.Image as image from sklearn.cluster import KMeans def loadData ...

  8. 这届网友实在是太有才了!用python爬取15万条《我是余欢水》弹幕

    年初时我们用数据解读了几部热度高,但评分差强人意的国产剧,而最近正午阳光带着两部新剧来了,<我是余欢水>和<清平乐>,截止到目前为止,这两部剧在豆瓣分别为7.5分和7.9分,算 ...

  9. python爬取《龙岭迷窟》的数据,看看质量剧情还原度到底怎么样

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

  10. L3 多层感知机

    **本小节用到的数据下载 1.涉及语句 import d2lzh1981 as d2l 数据1 : d2lzh1981 链接:https://pan.baidu.com/s/1LyaZ84Q4M75G ...