Description
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
Input
给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.
Output
输出你所找到的点,如果具有多个解,请输出编号最小的那个.
Sample Input
8
1 4
5 6
4 5
6 7
6 8
2 4
3 4
1 4
5 6
4 5
6 7
6 8
2 4
3 4
Sample Output
7
这题和NOIP2014 D1T2一个难度吧...
就是以1为根两遍dfs,分别求出子树的总深度和这个点为根的树的总深度
然后统计下哪个最大就行了
【刚刚才弃疗CF来做做这题醒醒脑】
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
struct line
{
int s,t;
int next;
}a[2000001];
int head[1000001];
int edge;
inline void add(int s,int t)
{
a[edge].next=head[s];
head[s]=edge;
a[edge].s=s;
a[edge].t=t;
}
bool v[1000001];
int fa[1000001];
long long son[1000001],ason[1000001],ans[1000001];
int n;
inline void dfs1(int d)
{
v[d]=true;
ason[d]=1;
int i;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(!v[t])
{
dfs1(t);
fa[t]=d;
ason[d]+=ason[t];
son[d]+=son[t];
}
}
son[d]+=ason[d]-1;
}
inline void dfs2(int d)
{
v[d]=true;
if(d!=1)
ans[d]=ans[fa[d]]-ason[d]+n-ason[d];
else
ans[d]=son[d];
int i;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(!v[t])
dfs2(t);
}
}
int main()
{
scanf("%d",&n);
int i;
int s,t;
for(i=1;i<=n-1;i++)
{
scanf("%d%d",&s,&t);
edge++;
add(s,t);
edge++;
add(t,s);
}
memset(v,false,sizeof(v));
dfs1(1);
memset(v,false,sizeof(v));
dfs2(1);
long long maxx=0;
int maxi;
for(i=1;i<=n;i++)
{
if(ans[i]>maxx)
{
maxx=ans[i];
maxi=i;
}
}
printf("%d\n",maxi);
return 0;
}