题目大意
求树上每个点到其他点的最大距离。
解题思路
首先随便选择一个顶点作为根然后跑一遍dfs,记录每个顶点以其为根能到达的最大深度和次大深度,然后再跑一遍dfs,对于每个顶点,如果要到达一个距离最大的点,要么就是原来中的子树中的距离最大的点,要么就是经过父节点的某个点。
代码
#include<bits/stdc++.h>
#define endl '
'
#define x first
#define y second
#define clr(arr,a) memset(arr, a, sizeof(arr))
#define IOS ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<ll, int> Pll;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int maxn = 1e4+10;
vector<P> e[maxn];
int n, dp[maxn][3], f[maxn];/*dp[u][0]是向下距离u最远的距离,
f[v]是向下距离u最远的顶点,dp[u][1]是向下的次远距离,dp[u][2]是经过父节点的最远距离*/
void dfs(int u) {
for (auto v : e[u]) {
dfs(v.y);
if (dp[u][0]<v.x+dp[v.y][0]) {
dp[u][1] = max(dp[u][1], dp[u][0]);
dp[u][0] = v.x+dp[v.y][0];
f[u] = v.y;
}
else dp[u][1] = max(dp[u][1], v.x+dp[v.y][0]);
}
}
void dfs2(int u) {
for (auto v : e[u]) {
if (f[u]==v.y) dp[v.y][2] = max(dp[u][1], dp[u][2])+v.x;
else dp[v.y][2] = max(dp[u][0], dp[u][2])+v.x;
dfs2(v.y);
}
}
int main(void) {
while(cin >> n) {
for (int i = 0; i<=n; ++i) e[i].clear(), f[i] = 0, dp[i][0] = dp[i][1] = dp[i][2] = 0;
for (int i = 2, a, b; i<=n; ++i) {
cin >> a >> b;
e[a].push_back({b, i});
}
dfs(1);
//for (int i = 1; i<=n; ++i) cout << dp[i][0] << ' '<< dp[i][1] << endl;
dfs2(1);
for (int i = 1; i<=n; ++i) cout << max(dp[i][0], dp[i][2]) << endl;
}
return 0;
}