题目链接
- 记 f[u] 为节点 u 第一步向儿子方向走的最远距离
- 记 g[u] 为节点 u 第一步向父亲方向走的最远距离
- 记 fa[u] 为节点 u 的父亲节点的编号
- f[u] = max{f[v] + w(u, v)} ,v是u的儿子
- g[u] = w(u, fa[u]) + max{g[p[u]], f[v] + w(fa[u], v)}, v 是 u 的兄弟
- 所以要做两边dfs,先求出f再求出g。
- 最后节点 u 的最远距离即为max{f[u], g[u]}。
#include <bits/stdc++.h>
using namespace std;
const int maxn = (int)1e4+100;
int n, f[maxn], g[maxn], fa[maxn];
vector< pair<int, int> > G[maxn];
void init(int n) {
memset(f, 0, sizeof(f));
memset(g, 0, sizeof(g));
memset(fa, 0, sizeof(fa));
for (int i = 1; i <= n; ++i) G[i].clear();
}
void dfs(int x, int par) {
fa[x] = par;
for (pair<int, int> pii : G[x]) {
int to = pii.first;
if (to == par) continue;
dfs(to, x);
f[x] = max(f[x], f[to] + pii.second);
}
}
void dfs2(int x, int par) {
int temp = 0;
g[x] = g[par];
for (pair<int, int> pii : G[par]) {
int to = pii.first;
if (to == fa[par]) continue;
if (to == x) temp = pii.second;
else {
g[x] = max(g[x], f[to] + pii.second);
}
}
g[x] += temp;
for (pair<int, int> pii : G[x]) {
int to = pii.first;
if (to == par) continue;
dfs2(to, x);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.precision(10);
cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
while (cin >> n) {
init(n);
for (int i = 2; i <= n; ++i) {
int u, val;
cin >> u >> val;
G[i].emplace_back(make_pair(u, val));
G[u].emplace_back(make_pair(i, val));
}
dfs(1, 0);
dfs2(1, 0);
for (int i = 1; i <= n; ++i) {
cout << max(f[i], g[i]) << '\n';
}
}
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}