Title link: HDU2196 Computer [Tree DP]
Meaning of the question: give you a tree, find the farthest distance of the point that all nodes can reach in the tree;
Analysis: dp[i][0], representing the longest distance from vertex i to the subtree with vertex i; dp[i][1], representing the minimum of Tree(i’s parent node)-Tree(i) Long distance + the distance between i and the parent node of i; dp[i][0] can be quickly obtained by dfs1; dp[i][1] can be transferred from the parent node, and a longest mx1 and passing children must be maintained Node v1, second largest mx2 and child node v2. If v is v1 when updating, then it can only be transferred from mx2, otherwise it is transferred from mx1;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int maxn=1e5+7;
bool vis[maxn];
int dp[maxn][2];
struct node{int v,w;};
vector<node> g[maxn];
int n;
int dfs1(int u)
{
vis[u]=1;dp[u][0]=0;
for(auto i:g[u]) if(!vis[i.v]) dp[u][0]=max(dp[u][0],dfs1(i.v)+i.w);
return dp[u][0];
}
void dfs2(int u)
{
vis[u]=1;
int mx1=0,mx2=0,v1,v2;
for(auto i:g[u])
{
if(vis[i.v]) continue;
int kk=dp[i.v][0]+i.w;
if(kk>mx1) {mx2=mx1;v2=v1;mx1=kk;v1=i.v;}
else if(kk==mx1 || kk>mx2) mx2=kk,v2=i.v;
}
if(u!=1)
{
int kk=dp[u][1],v=-1;
if(kk>mx1) {mx2=mx1;v2=v1;mx1=kk;v1=v;}
else if(kk==mx1 || kk>mx2) mx2=kk,v2=v;
}
for(auto i:g[u])
{
if(vis[i.v]) continue;
if(i.v==v1) dp[i.v][1]=mx2+i.w;
else dp[i.v][1]=mx1+i.w;
dfs2(i.v);
}
}
int main()
{
while(~scanf("%d",&n) && n)
{
for(int i=0;i<n;i++) g[i].clear();
for(int u=2;u<=n;u++)
{
int v,w;scanf("%d%d",&v,&w);
g[u].pb({v,w});g[v].pb({u,w});
}
memset(dp,-1,sizeof(dp));
memset(vis,0,sizeof(vis));
dfs1(1);
memset(vis,0,sizeof(vis));
dfs2(1);
for(int i=1;i<=n;i++) printf("%d\n",max(dp[i][0],dp[i][1]));
}
return 0;
}