题目大意:给你一棵树,求任意两点间的最长距离。
输入:
第一行一个数
n
,表示树的节点数。
以后
设
说白了,
状态转移请自行脑补。。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mp make_pair
#define X first
#define Y second
using namespace std;
typedef pair<int, int> pii;
inline int read()
{
int x = 0, f = 1, t = getchar();
while(t < '0' || t > '9') t == '-' ? f = -1 : 0, t = getchar();
while(t >= '0' && t <= '9') x = (x<<1) + (x<<3) + t-'0', t = getchar();
return x * f;
}
const int maxn = 10005;
const int maxm = 20005;
struct Edge
{
int u, v, w;
Edge(int u = 0, int v = 0, int w = 0): u(u), v(v), w(w) {}
};
int n, m;
int head[maxn], next[maxm], h[maxn];
Edge edge[maxm];
pii f[maxn], g[maxn], tmp;
inline void relax(int &x, int y)
{
y > x ? x = y : 0;
}
inline void adde(int a, int b, int c)
{
edge[m] = Edge(a, b, c), next[m] = head[a], head[a] = m++;
}
inline void addedge(int c, int b, int a)
{
adde(a, b, c), adde(b, a, c);
}
void init()
{
memset(head, -1, sizeof(head));
n = read(), m = 0;
for(int i = 2; i <= n; ++i)
addedge(read(), i, read());
}
void solve1(int x, int p)
{
for(int i = head[x]; i != -1; i = next[i])
{
Edge &e = edge[i];
if(e.v != p)
{
solve1(e.v, x);
tmp = mp(f[e.v].X + e.w, e.v);
if(tmp.X > f[x].X) g[x] = f[x], f[x] = tmp;
else if(tmp.X > g[x].X) g[x] = tmp;
}
}
}
void solve2(int x, int p)
{
for(int i = head[x]; i != -1; i = next[i])
{
Edge &e = edge[i];
if(e.v != p)
{
if(f[x].Y == e.v) relax(h[e.v], g[x].X + e.w);
else relax(h[e.v], f[x].X + e.w);
relax(h[e.v], h[x] + e.w);
solve2(e.v, x);
}
}
}
void work()
{
solve1(1, 0);
solve2(1, 0);
for(int i = 1; i <= n; ++i)
printf("%d\n", max(f[i].X, h[i]));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
init();
work();
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}