题目地址:POJ 2196
题目:
给定一棵树,输出每个点能够到达的最远的距离
解决:
找到树的直径,分别用两端做树根,记录每个点到树根的距离,然后输出。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int n;
int h[N], e[N], w[N], ne[N], idx;
int d1[N], d2[N], maxv;
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
void dfs(int x, int father, int res, int d[])
{
d[x] = res;
if (d[x] > d[maxv]) maxv = x;
for (int i = h[x]; ~i; i = ne[i])
{
int y = e[i], z = w[i];
if (y == father) continue;
dfs(y, x, res + z, d);
}
}
int main()
{
while (cin >> n)
{
memset(h, -1, sizeof h);
idx = 0;
for (int i = 2; i <= n; i ++ )
{
int b, c; scanf("%d%d", &b, &c);
add(i, b, c), add(b, i, c);
}
maxv = 0;
dfs(1, -1, 0, d1);
d1[maxv] = 0;
dfs(maxv, -1, 0, d1); // 以直径的端点为根,求每个点到根节点的距离,下同
d2[maxv] = 0;
dfs(maxv, -1, 0, d2);
for (int i = 1; i <= n; i ++ )
printf("%d\n", max(d1[i], d2[i]));
}
return 0;
}