树形dp经典题
考虑只维护一个最长路会使得所选路径重复
因此可以再维护一个次长路来消除路径重复...
然后这题就结束了
#include<bits/stdc++.h> #define MAXN 10005 using namespace std; int n,tot; int h[MAXN],f[MAXN][3],fr[MAXN]; struct node{ int from,to,cost,next; }e[MAXN<<1]; void init(){ tot=0; memset(h,-1,sizeof(h)); memset(f,0,sizeof(f)); memset(fr,0,sizeof(fr)); } void add(int x,int y,int z){ tot++; e[tot].from=x; e[tot].to=y; e[tot].cost=z; e[tot].next=h[x]; h[x]=tot; } void dfs(int now,int fa){ int mx=0,mr=0;//max maxl for(int i=h[now];i!=(-1);i=e[i].next){ if(e[i].to!=fa){ dfs(e[i].to,now); if(mx<f[e[i].to][0]+e[i].cost)mr=mx,mx=f[e[i].to][0]+e[i].cost,fr[now]=e[i].to; else if(mr<f[e[i].to][0]+e[i].cost)mr=f[e[i].to][0]+e[i].cost; } } f[now][0]=mx; f[now][1]=mr; } void dfs2(int now,int fa){ for(int i=h[now];i!=(-1);i=e[i].next){ if(e[i].to!=fa){ f[e[i].to][2]=max(f[e[i].to][2],f[now][2]+e[i].cost); if(fr[now]!=e[i].to)f[e[i].to][2]=max(f[e[i].to][2],f[now][0]+e[i].cost); else f[e[i].to][2]=max(f[e[i].to][2],f[now][1]+e[i].cost); dfs2(e[i].to,now); } } } int main(){ while(scanf("%d",&n)==1){ init(); for(int i=2;i<=n;i++){ int p,c;cin>>p>>c; add(p,i,c); add(i,p,c); } dfs(1,1); dfs2(1,1); for(int i=1;i<=n;i++){ cout<<max(max(f[i][0],f[i][1]),f[i][2])<<endl; } } }
经验:再一些情况下,解决重复问题可以采用维护次答案来解决....
或者通过设计一些不会重复的状态....
更或者是根据状态来解决重复
或者通过一些特殊手段(数学? 重新构造一个....或者是逐步去重(比较玄学))