码迷,mamicode.com
首页 > 其他好文 > 详细

HDU2196 Computer(树形DP)

时间:2016-03-11 23:58:27      阅读:366      评论:0      收藏:0      [点我收藏+]

标签:

LightOJ1257一样,之前我用了树分治写了。其实原来这题是道经典的树形DP,感觉这个DP不简单。。

  • dp[0][u]表示以u为根的子树中的结点与u的最远距离
  • dp[1][u]表示以u为根的子树中的结点与u的次远距离

这两个可以一遍dfs通过儿子结点转移得到。显然dp[0][u]就是u的一个可能的答案,即u往下走的最远距离,还缺一部分就是u往上走的最远距离:

  • dp[2][u]表示u往上走的最远距离

对于这个的转移,分两种情况,是这样的:

  1. dp[2][v] = max( dp[0][u]+weight(u,v) , dp[2][u]+weight(u,v) ) (v是u的儿子 且 u往下走的最远距离不经过v)
  2. dp[2][v] = max( dp[1][u]+weight(u,v) , dp[2][u]+weight(u,v) ) (v是u的儿子 且 u往下走的最远距离经过v)

再一遍dfs就能得到。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define MAXN 11111
 6 struct Edge{
 7     int v,w,next;
 8 }edge[MAXN<<1];
 9 int NE,head[MAXN];
10 void addEdge(int u,int v,int w){
11     edge[NE].v=v; edge[NE].w=w;
12     edge[NE].next=head[u]; head[u]=NE++;
13 }
14 long long d[3][MAXN];
15 int idx[MAXN];
16 void dfs0(int u,int fa){
17     long long mx0=0,mx1=0;
18     for(int i=head[u]; i!=-1; i=edge[i].next){
19         int v=edge[i].v;
20         if(v==fa) continue;
21         dfs0(v,u);
22         if(mx0<=d[0][v]+edge[i].w) mx1=mx0,mx0=d[0][v]+edge[i].w,idx[u]=v;
23         else if(mx1<d[0][v]+edge[i].w) mx1=d[0][v]+edge[i].w;
24         else if(mx1<d[1][v]+edge[i].w) mx1=d[1][v]+edge[i].w;
25     }
26     d[0][u]=mx0; d[1][u]=mx1;
27 }
28 void dfs1(int u,int fa){
29     for(int i=head[u]; i!=-1; i=edge[i].next){
30         int v=edge[i].v;
31         if(v==fa) continue;
32         if(idx[u]==v) d[2][v]=max(d[1][u]+edge[i].w,d[2][u]+edge[i].w);
33         else d[2][v]=max(d[0][u]+edge[i].w,d[2][u]+edge[i].w);
34         dfs1(v,u);
35     }
36 }
37 int main(){
38     int n,a,b;
39     while(~scanf("%d",&n)){
40         NE=0;
41         memset(head,-1,sizeof(head));
42         for(int i=2; i<=n; ++i){
43             scanf("%d%d",&a,&b);
44             addEdge(i,a,b); addEdge(a,i,b);
45         }
46         memset(d,0,sizeof(d));
47         dfs0(1,1);
48         dfs1(1,1);
49         for(int i=1; i<=n; ++i){
50             printf("%lld\n",max(d[0][i],d[2][i]));
51         }
52     }
53     return 0;
54 }

 

HDU2196 Computer(树形DP)

标签:

原文地址:http://www.cnblogs.com/WABoss/p/5267488.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!