1131: [POI2008]Sta
Time Limit: 10 Sec Memory Limit: 162 MB[ Submit][ Status][ Discuss]
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
HINT
sum表示子树,anti表示父亲作为子树的值
#include<bits/stdc++.h>
using namespace std;
const int N = 1000000 + 5;
long long siz[N],anti[N],sum[N],ans; int ans2,last[N*2],cnt,n;
struct Edge{ int to,next; }e[N*2];
void insert( int u, int v ){
e[++cnt].to = v; e[cnt].next = last[u]; last[u] = cnt;
e[++cnt].to = u; e[cnt].next = last[v]; last[v] = cnt;
}
void dfs( int x, int f ){
siz[x] = 1;
for( int i = last[x]; i; i = e[i].next )
if( e[i].to ^ f ){
dfs( e[i].to, x );
siz[x] += siz[e[i].to];
sum[x] += (sum[e[i].to]+siz[e[i].to]);
}
}
void dfs2( int x, int f ){
for( int i = last[x]; i; i = e[i].next )
if( e[i].to ^ f ){
anti[e[i].to] = anti[x] + sum[x] - sum[e[i].to] - siz[e[i].to] + n - siz[e[i].to];
dfs2( e[i].to, x );
}
if( anti[x] + sum[x] >= ans ){
if( anti[x] + sum[x] > ans ) ans = anti[x] + sum[x], ans2 = x;
else ans2 = min( ans2, x );
}
}
int main(){
scanf("%d", &n);
for( int i = 1,u,v,w; i < n; i++ ){
scanf("%d%d", &u, &v);
insert( u, v );
}
dfs( 1, 0 ); dfs2( 1, 0 );
printf("%d\n", ans2);
return 0;
}