题目:Computer
题意:给定一棵N个节点的树已经边的长度,求出每个点到其它点的最长距离。
经典树形dp题,一次dfs求出每个点到孩子的最长距离(第一长和第二长),第二次dfs求出最终答案。
题外话:近期屡屡被树形dp虐,看出来也写不出程序,写出来也调不出样例,调出个样例也还是个WA,于是痛定思痛,回去好好复习树形dp。。。
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int N = 100010;
#define pb push_back
vector<int> V[N];
vector<int> G[N];
int n, dp[N][2], to[N][2], ans[N];
void dfs(int x){
dp[x][0]=dp[x][1]=-1;
for(int i=0; i<V[x].size(); i++){
int j = V[x][i];
int d = G[x][i];
dfs(j);
d += dp[j][0];
if(d>dp[x][1]){
dp[x][1]=d;
to[x][1]=j;
}
if(dp[x][1]>dp[x][0]){
swap(dp[x][0], dp[x][1]);
swap(to[x][0], to[x][1]);
}
}
if(dp[x][0]==-1) dp[x][0]=0;
}
void dfs2(int x, int D){
ans[x] = max(D, dp[x][0]);
for(int i=0; i<V[x].size(); i++){
int j = V[x][i];
int d = G[x][i];
if(j==to[x][0]){
if(dp[x][1]==-1) dfs2(j, D+d);
else dfs2(j, max(D,dp[x][1])+d);
}
else{
dfs2(j, max(D,dp[x][0])+d);
}
}
}
int main(){
while(~scanf("%d", &n)){
for(int i=1; i<=n; i++){
V[i].clear();
G[i].clear();
}
int a, b;
for(int i=2; i<=n; i++){
scanf("%d %d", &a, &b);
V[a].pb(i); G[a].pb(b);
}
dfs(1);
dfs2(1, 0);
for(int i=1; i<=n; i++) printf("%d\n", ans[i]);
}
return 0;
}