STA树的深度

给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

Input

给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.

Output

输出你所找到的点,如果具有多个解,请输出编号最小的那个.

Sample Input8 1 4 5 6 4 5 6 7 6 8 2 4 3 4Sample Output7

分析:这个题如果以每个根dfs的话肯定会超时。

   定义size[i]为以i为根的子树的节点数,f[i]为以为根的树的所有点的深度

   我们不难发现f[v] = f[u] + n - 2 * size[v]

   把根由u变成v,v的子树节点所有的深度都减1,一共减少了size[v],v以上一共有n-size[v]个点,深度都加1,加了n-size[v]所以一共是n-2*size[v]

   所以我们先dfs把每个点的深度和子树大小跑出来,再跑一遍dfs把f[i]算出来,最后遍历一遍f[i]就可以了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1000010;
 4 struct edge
 5 {
 6     int to,nxt;
 7 }e[maxn<<1];
 8 int n,cnt,id;
 9 int head[maxn];
10 long long ans;
11 long long f[maxn],d[maxn],size[maxn], t;
12 inline void Add(int u,int v)
13 {
14     e[++cnt].nxt=head[u];
15     head[u]=cnt;
16     e[cnt].to=v;
17 }
18 void Dfs1(int x,int fa)
19 {
20     size[x]=1;d[x]=d[fa]+1;
21     for(int i=head[x];i;i=e[i].nxt)
22     {
23         int y=e[i].to;
24         if(y==fa) continue;
25         Dfs1(y,x);
26         size[x]+=size[y];
27     }
28 }
29 void Dfs2(int x,int fa)
30 {
31     for(int i=head[x];i;i=e[i].nxt)
32     {
33         int y=e[i].to;
34         if(y==fa) continue;
35         f[y]=f[x]+n-2*size[y];
36         Dfs2(y,x);
37     }
38 }
39 int main()
40 {
41     scanf("%d",&n);
42     for(int i=1;i<n;i++)
43     {
44         int u,v;scanf("%d%d",&u,&v);
45         Add(u,v),Add(v,u);
46     }
47     Dfs1(1,0);
48     for(int i=1;i<=n;i++) f[1]+=d[i];
49     Dfs2(1,0);
50     for(int i=1;i<=n;i++) if(ans<f[i]) ans=f[i],t=i;
51     printf("%d",t);
52     return 0;
53 }
View Code

 

posted @ 2020-04-13 16:04  ghosh  阅读(195)  评论(0编辑  收藏  举报
莫挨老子!