ssl 2688 根

来源:互联网 发布:入侵学校数据库 编辑:程序博客网 时间:2024/05/21 10:44

Description

一天,小B得到了一棵n个节点的树。无聊至极的小B想要找出一个点,使得以这个点为根时,所有点的深度之和最大。但小B打开手机,发现他最爱的re:creator又更新啦,于是这个无聊的任务就交给你了。

Input

第一行一个数n,接下来n-1行,每行两个数,表示一条边。

Output

一行一个整数,表示所有点深度之和的最大值的那个点。
如果最大值相同,输出拥有更小编号的点

Sample Input

5
2 1
3 1
4 2
5 3

Sample Output

4
Hint

对于前30%的数据,n<=1000.
对于前100%的数据,n<=1000000.

思路

dfs一次只有就可以o(1)换根的。

代码

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<queue>#include<algorithm>#define N 3000000using namespace std;struct NOTE{    int x,y,next;}e[N];int head[N];int low[N];int maxn,ans,dep,n;int tot;void add(int x,int y){    e[++tot]=(NOTE){x,y,head[x]},head[x]=tot;    e[++tot]=(NOTE){y,x,head[y]},head[y]=tot;}void dfs(int x,int r,int d){    dep+=d;    low[x]=1;    for (int i=head[x];i!=0;i=e[i].next)    {        if (e[i].y==r) continue;        dfs(e[i].y,x,d+1);        low[x]+=low[e[i].y];    }}void find(int x,int r,int dep){    if (x!=1)    {        dep=dep-low[x]+(n-low[x]);        if ((dep>maxn)||((dep==maxn)&&(ans>x)))        {                    maxn=dep;            ans=x;                    }    }    for (int i=head[x];i!=0;i=e[i].next)    {        if (e[i].y==r) continue;        find(e[i].y,x,dep);    }}int main(){    tot=1;    scanf("%d",&n);    for (int i=1;i<=n-1;i++)    {        int x,y;        scanf("%d%d",&x,&y);        add(x,y);    }    dfs(1,0,0);    maxn=dep;    ans=1;    find(1,0,dep);    printf("%d",ans);}
原创粉丝点击