一开始就想到了树形dp,然后下午就一直在做其他事中思考==
首先,我用一个dfs来找每一个节点所对应的树中到该节点最远距离dis1[],这个很简单,然后
。。。。。。
我再思考如何计算这个点到他的兄弟和父亲最远
。。。。。。
好难描述我的想法历程,语文好差T_T==大概就是这样,我在刚才的dfs中记录了最远的话是哪一个儿子给他id[]和次远距离的长度dis2[]
接着我需要再来一个节点来计算up数组,up数组表示的是:max(兄弟中到他最远距离,父亲及父亲的兄弟及父亲的父亲到他最远距离)
那么这个dfs如何转移?thinking==
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int next[50005],head[50005],point[50005],value[50005],now; 6 int dis1[50005],dis2[50005],id[50005],up[50005]; 7 void add(int x,int y,int w) 8 { 9 next[++now]=head[x]; 10 head[x]=now; 11 point[now]=y; 12 value[now]=w; 13 } 14 void dfs1(int pre,int u) 15 { 16 int i,v,w; 17 dis1[u]=dis2[u]=id[u]=0; 18 for (i=head[u];i;i=next[i]) 19 { 20 v=point[i]; w=value[i]; 21 if (v==pre) continue; 22 dfs1(u,v); 23 if (dis1[v]+w>dis1[u]){ 24 dis1[u]=dis1[v]+w; 25 id[u]=v; 26 } 27 } 28 for (i=head[u];i;i=next[i]) 29 { 30 v=point[i]; w=value[i]; 31 if (v==pre||v==id[u]) continue; 32 if (dis1[v]+w>dis2[u]) dis2[u]=dis1[v]+w; 33 } 34 } 35 void dfs2(int pre,int u) 36 { 37 int i,v,w; 38 for (i=head[u];i;i=next[i]) 39 { 40 v=point[i]; w=value[i]; 41 if (v==pre) continue; 42 up[v]=up[u]+w; 43 if (id[u]!=v) up[v]=max(up[v],dis1[u]+w); 44 else up[v]=max(up[v],dis2[u]+w); 45 dfs2(u,v); 46 } 47 } 48 int main() 49 { 50 int n,i,x,y; 51 while (~scanf("%d",&n)) 52 { 53 memset(head,0,sizeof(head)); 54 now=0; 55 for (i=2;i<=n;i++) 56 { 57 scanf("%d%d",&x,&y); 58 add(x,i,y); add(i,x,y); 59 } 60 memset(dis1,0,sizeof(dis1)); 61 memset(dis2,0,sizeof(dis2)); 62 memset(id,0,sizeof(id)); 63 dfs1(0,1); 64 memset(up,0,sizeof(up)); 65 dfs2(0,1); 66 for (i=1;i<=n;i++) printf("%d\n",max(dis1[i],up[i])); 67 } 68 return 0; 69 }