大致题意:每一台电脑和某些电脑相连,所有电脑构成了一颗树。现在,需要求每台电脑传送信息的最大距离,也就是到达叶子节点的最大距离。很经典的一道树形DP,大致思路:任选一个节点作为根节点,然后用DFS跑出每个节点向下的最大距离和次大距离。然后再进行一次dfs,找出每个节点向父节点可以走的距离,最后比较一下就是结果了。(解题过程不能说得太清楚了,略加提示,请仔细思考)。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+100;
int head[maxn];
int dp[maxn][3];
bool vis[maxn];
int tot;
struct node
{
int v,next,val;
} arr[maxn<<1];
void add(int u,int v,int val)
{
arr[tot].next=head[u];
arr[tot].v=v;
arr[tot].val=val;
head[u]=tot++;
}
void init(int n)
{
tot=0;
for(int i=0; i<=n; ++i)
head[i]=-1;
}
int dfs1(int u,int c)
{
int v;
int temp=0;
for(int i=head[u]; i!=-1; i=arr[i].next)
{
v=arr[i].v;
if(vis[v])
continue;
vis[v]=true;
temp=dfs1(v,arr[i].val);
vis[v]=false;
if(temp>=dp[u][0])
{
dp[u][1]=dp[u][0];
dp[u][0]=temp;
}
else if(temp>dp[u][1])
dp[u][1]=temp;
}
return dp[u][0]+c;
}
void dfs2(int u)
{
int v;
for(int i=head[u]; i!=-1; i=arr[i].next)
{
v=arr[i].v;
if(vis[v])
continue;
vis[v]=true;
dp[v][2]=max(dp[u][2],(dp[u][0]-dp[v][0]-arr[i].val?dp[u][0]:dp[u][1]))+arr[i].val;
dfs2(v);
vis[v]=false;
}
}
int main()
{
int n;
while(cin>>n)
{
memset(dp,0,sizeof(dp));
init(n);
int v,val;
for(int i=2; i<=n; ++i)
{
cin>>v>>val;
add(i,v,val);
add(v,i,val);
}
vis[1]=true;
dfs1(1,0);
dfs2(1);
for(int i=1;i<=n;++i)
cout<<max(dp[i][0],dp[i][2])<<endl;
}
return 0;
}