这是一道十分经典的树形DP了,两个dfs,第一个dfs找到所有子节点能到达的最远距离和次远距离,第二个dfs就是从父节点更新这些距离
AC代码:
<span style="font-family:Verdana;">#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int MAXN=11000; /* int maxn[MAXN];该节点往下到叶子的最大距离 int smaxn[MAXN];次大距离 int maxid[MAXN];最大距离对应的序号 int smaxid[MAXN];次大的序号 */ struct Edge{ int from,to,cost,next; Edge(){} Edge(int from,int to,int cost,int next){ this->from=from; this->to=to; this->cost=cost; this->next=next; } }e[MAXN*2]; int head[MAXN*2],maxn[MAXN]; int maxid[MAXN],smaxn[MAXN],smaxid[MAXN],tot; void init(){ memset(head,-1,sizeof(head)); tot=0; } void add_edge(int u,int v,int c){ e[tot]=Edge(u,v,c,head[u]); head[u]=tot++; e[tot]=Edge(v,u,c,head[v]); head[v]=tot++; } void dfs1(int u,int fa){ maxn[u]=0; smaxn[u]=0; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; //cout<<u<<" "<<v<<endl; if(v==fa) continue; dfs1(v,u); if(smaxn[u]<maxn[v]+e[i].cost){ smaxn[u]=maxn[v]+e[i].cost; smaxid[u]=v; if(smaxn[u]>maxn[u]){ swap(smaxn[u],maxn[u]); swap(smaxid[u],maxid[u]); } } } } void dfs2(int u,int fa){ for(int i=head[u];~i;i=e[i].next){ int v=e[i].to; if(v==fa) continue; if(v==maxid[u]){ if(e[i].cost+smaxn[u]>smaxn[v]){ smaxn[v]=e[i].cost+smaxn[u]; smaxid[v]=u; if(smaxn[v]>maxn[v]){ swap(smaxn[v],maxn[v]); swap(smaxid[v],maxid[v]); } } } else{ if(e[i].cost+maxn[u]>smaxn[v]){ smaxn[v]=e[i].cost+maxn[u]; smaxid[v]=u; if(smaxn[v]>maxn[v]){ swap(smaxn[v],maxn[v]); swap(maxid[v],smaxid[v]); } } } dfs2(v,u); } } int main(){ int t; while(~scanf("%d",&t)){ init(); for(int v=2;v<=t;v++){ int u,w; scanf("%d%d",&u,&w); add_edge(v,u,w); } dfs1(1,-1); dfs2(1,-1); for(int i=1;i<=t;i++) printf("%d\n",maxn[i]); } return 0; }</span>
