洛谷 P3478 POI 2008 STA-Station
url: https://www.luogu.com.cn/problem/P3478
tag:
树形DP,POI,2008
思路:
利用两次dfs,第一次求出以1为根节点时深度和,以及各个节点为根时的子树大小,之后利用第二次dfs求出每个节点为根时的深度和。这个方法称为二次扫描。
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
int h[N], e[N * 2], ne[N * 2], idx;
int n;
long long res, id;
long long d[N], s[N], f[N];
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
void dfs(int u, int fa)
{
s[u] = 1; d[u] = d[fa] + 1;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == fa) continue;
dfs(j, u);
s[u] += s[j];
}
}
void dfs2(int u, int fa)
{
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == fa) continue;
f[j] = f[u] + n - 2 * s[j];
dfs2(j, u);
}
}
int main()
{
cin >> n;
memset(h, -1, sizeof h);
for (int i = 0; i < n - 1; i ++)
{
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
dfs(1, 0);
for (int i = 1; i <= n; i ++) f[1] += d[i];
dfs2(1, 0);
for (int i = 1; i <= n; i ++) if (f[i] > res) res = f[i], id = i;
cout << id << endl;
return 0;
}
当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »