标签:
其实很简单,先计算子树的max,再计算父树的max就OK了;
-----------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
int x=0; int f=1;
char c=getchar();
while(!isdigit(c)){
if(c==‘-‘) f=-1;
c=getchar();
}
while(isdigit(c)){
x=x*10+c-‘0‘;
c=getchar();
}
return x*f;
}
struct edge{
int to,w;
edge*next;
};
edge e[10005],*pt,*head[10005];int f[10005][3];
void add(int s,int t,int w){
pt->to=t; pt->w=w;
pt->next=head[s];
head[s]=pt++;
}
void dp1(int x){
for(edge*ee=head[x];ee;ee=ee->next){
int to=ee->to; int w=ee->w;
dp1(to);
if(f[to][1]+w>f[x][1]){
f[x][0]=f[x][1];f[x][1]=f[to][1]+w;
}
else if(f[to][1]+w>f[x][0]){
f[x][0]=f[to][1]+w;
}
}
return ;
}
void dp2(int x,int fa,int len){
if(f[x][1]+len==f[fa][1]){
f[x][2]=max(f[fa][2],f[fa][0]);
}
else{
f[x][2]=max(f[fa][2],f[fa][1]);
}
f[x][2]+=len;
for(edge*ee=head[x];ee;ee=ee->next){
int to=ee->to;int w=ee->w;
dp2(to,x,w);
}
return ;
}
int main(){
int n;
while(scanf("%d",&n)==1){
clr(f,0);clr(head,0);
pt=e;
for(int i=2;i<=n;i++){
int u=read(),v=read();
add(u,i,v);
}
/*rep(i,n){
cout<<i<<endl;
for(edge*ee=head[i];ee;ee=ee->next)
printf("%d %d\n",ee->to,ee->w);
}*/
dp1(1);
dp2(1,0,0);
rep(i,n) printf("%d\n",max(f[i][1],f[i][2]));
}
return 0;
}
-----------------------------------------------------------------------------------
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4926 Accepted Submission(s): 2475
标签:
原文地址:http://www.cnblogs.com/fighting-to-the-end/p/5049554.html