hdu2196 树形dp(求距离树上每个点最远的距离)

一开始就想到了树形dp,然后下午就一直在做其他事中思考==

首先,我用一个dfs来找每一个节点所对应的树中到该节点最远距离dis1[],这个很简单,然后

。。。。。。

我再思考如何计算这个点到他的兄弟和父亲最远

。。。。。。

好难描述我的想法历程,语文好差T_T==大概就是这样,我在刚才的dfs中记录了最远的话是哪一个儿子给他id[]和次远距离的长度dis2[]

接着我需要再来一个节点来计算up数组,up数组表示的是:max(兄弟中到他最远距离,父亲及父亲的兄弟及父亲的父亲到他最远距离)

那么这个dfs如何转移?thinking==

 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 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196

转载于:https://www.cnblogs.com/xiao-xin/articles/4232275.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值