树的深度(我觉得没毛病)
题干
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
Input
给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.
Output
输出你所找到的点,如果具有多个解,请输出编号最小的那个.
Example
8
1 4
5 6
4 5
6 7
6 8
2 4
3 4
7
简单粗暴的题意,直接莽就完事了。
先搞个小点的例子试试水(我是把根节点的深度设为了0,其实你设1设几都没关系)
简单明了对吧,那我把根换一下呢?
我们会发现,我们把3作为根,那么包括3在内的3的子树的深度都减小了1,而1和2的深度都增加了1。那么规律是不是显而易见:
ans[儿砸]=(ans[爹]-siz[儿砸] )+(n-siz[儿砸] )
直接两遍dfs,第一遍处理完siz[]和ans[1](我们第一遍默认以1为根,当然你以别的为根也不是不行),第二遍再按找到的规律dfs更新答案即可
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1000000+10;
long long head[maxn],len=0,ans[maxn],siz[maxn];
long long maxx;
int n,flag;
struct Edge{
int next,to;
}edge[maxn<<1];
void Add(int u,int v){
edge[++len].to=v;
edge[len].next=head[u];
head[u]=len;
}
void Dfs1(int u,int fa,int dep){
siz[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa) continue;
Dfs1(v,u,dep+1);
siz[u]+=siz[v];
ans[1]+=dep+1;
}
}
void Dfs2(int u,int fa){
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa) continue;
ans[v]=ans[u]+n-2*siz[v];
if(ans[v]>maxx){
maxx=ans[v];
flag=v;
}
else if(ans[v]==maxx&&flag>v){
flag=v;
}
Dfs2(v,u);
}
}
int main(){
cin>>n;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
Add(u,v),Add(v,u);
}
Dfs1(1,0,0);
maxx=ans[1],flag=1;
Dfs2(1,0);
cout<<flag<<endl;
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· 盘点!HelloGitHub 年度热门开源项目
· DeepSeek V3 两周使用总结
· 02现代计算机视觉入门之:什么是视频
· C#使用yield关键字提升迭代性能与效率
· 回顾我的软件开发经历(1)