https://vjudge.net/contest/363991#problem/A
超妙的树形dp
一个递归,一个递推
f[i]表示i结点往下走的最远距离,g[i]表示往上走的最远距离
f[i]=max(f[j])+i->v;
g[i]=max(g[pa],f[e[pa]->n]+e[pa]->v)+i->v;
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 100010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) using namespace std; long long n,x,y; long long d[N]; long long f[N],g[N];//f[]表示当前的节点到其叶子结点的最短距离,g[]表示这个点往上走的最大距离 struct node{ long long n; long long v; node *next; }*e[N]; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } void clear(){ memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); memset(e,0,sizeof(e)); } void push(long long x,long long y,long long v){ node *p; p=new node(); p->n=y; p->v=v; if(e[x]==0) e[x]=p; else{ p->next=e[x]->next; e[x]->next=p; } } long long dfs(long long x,long long fa){ for(node *i=e[x];i;i=i->next){ if(i->n!=fa) f[x]=max(f[x],dfs(i->n,x)+i->v); } return f[x]; } void bfs(long long x,long long fa,long long F){ long long temp=0; for(node *i=e[fa];i;i=i->next){ if(i->n!=F&&i->n!=x) g[x]=max(g[x],f[i->n]+i->v); else if(i->n==x) temp=i->v; } if(fa!=F) g[x]=max(g[fa],g[x])+temp; for(node *i=e[x];i;i=i->next){ if(i->n!=fa) bfs(i->n,x,fa); } } signed main(){ while(cin>>n){ clear(); For(i,2,n){ in(x);in(y); push(i,x,y); push(x,i,y); } dfs(1,1); bfs(1,0,0); For(i,1,n) o(max(f[i],g[i])),p('\n'); } return 0; }