BZOJ 1131: [POI2008]Sta( dfs )
对于一棵树, 考虑root的答案向它的孩子转移, 应该是 ans[son] = (ans[root] - size[son]) + (n - size[son]).
so , 先 dfs 预处理一下, 然后再 DFS 求出各点答案 , 取最优即可
-----------------------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define rep(i ,n) for(int i=0; i < n; ++i)
#define clr(x ,c) memset(x, c, sizeof(x))
using namespace std;
typedef long long ll;
const int maxn = 1000005;
struct edge {
int to;
edge*next;
} E[maxn << 1], *pt = E, *head[maxn];
void add(int u, int v) {
pt->to = v;
pt->next = head[u];
head[u] = pt++;
}
#define add_edge(u, v) add(u, v), add(v, u)
int size[maxn], dep[maxn], n;
ll ans[maxn];
void init() {
clr(head, 0);
cin >> n;
rep(i, n - 1) {
int u, v;
scanf("%d%d", &u, &v);
u--, v--;
add_edge(u, v);
}
}
void dfs(int x, int fa) {
size[x] = 1;
for(edge*e= head[x]; e; e = e->next) if(e->to != fa) {
ans[0] += (dep[e->to] = dep[x] + 1);
dfs(e->to, x);
size[x] += size[e->to];
}
}
void DFS(int x, int fa) {
for(edge*e = head[x]; e; e = e->next) if(e->to != fa) {
ans[e->to] = ans[x] + n - 2 * size[e->to];
DFS(e->to, x);
}
}
void work() {
ans[0] = dep[0] = 0;
dfs(0, -1);
DFS(0, -1);
cout << max_element(ans, ans + n) - ans + 1 << "\n";
}
int main(){
freopen( "test.in" , "r" , stdin );
init();
work();
return 0;
}
-----------------------------------------------------------------------------------------------
1131: [POI2008]Sta
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 870 Solved: 271
[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
Source