Description
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.
Solution
随手点开没想到是水题
最开始考虑的是换根后深度区间+1/-1,询问就是区间求和,然后发现我并不会用树状数组区间修改区间求和
然后就发现这个东西只要树上dp一下就出来了
Code
#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int N=2000005;
const int E=2000005;
struct edge {int y,next;} e[E];
int size[N],dep[N],n,ans;
int ls[N],edCnt;
LL f[N];
void add_edge(int x,int y) {
e[++edCnt]=(edge) {y,ls[x]}; ls[x]=edCnt;
e[++edCnt]=(edge) {x,ls[y]}; ls[y]=edCnt;
}
void dfs1(int now,int fa) {
f[1]+=dep[now];
size[now]=1;
for (int i=ls[now];i;i=e[i].next) {
if (e[i].y==fa) continue;
dep[e[i].y]=dep[now]+1;
dfs1(e[i].y,now);
size[now]+=size[e[i].y];
}
}
void dfs2(int now,int fa) {
if (f[now]>f[ans]||f[now]==f[ans]&&now<ans) ans=now;
for (int i=ls[now];i;i=e[i].next) {
if (e[i].y==fa) continue;
f[e[i].y]=f[now]+n-2*size[e[i].y];
dfs2(e[i].y,now);
}
}
int main(void) {
scanf("%d",&n);
rep(i,2,n) {
int x,y; scanf("%d%d",&x,&y);
add_edge(x,y);
}
dfs1(1,0); dfs2(1,0);
printf("%d\n", ans);
return 0;
}