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

HDU 2196 - Computer

时间:2017-07-15 22:47:22      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:href   lan   struct   csdn   name   mem   hdu   com   [1]   

参考来自http://blog.csdn.net/shuangde800/article/details/9732825的思路:

 

技术分享

 

跟思路中不太相同的是,我们如下设置DP数组:

dp[i][0] : 表示以i为根的子树中的结点与i的最大距离

dp[i][1] : 表示以i为根的子树中的结点与u的次大距离(即上述思路中的secondDist)

dp[i][2] : 表示i往父亲节点方向走的最大距离

 

同样的,我们也做两次DFS,但是第一次的时候,我们将dp[i][0]和dp[i][1]一起算出来;

第二次DFS就可以直接用dp[i][0]和dp[i][1]。

 

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<vector>
 4 #include<cstring>
 5 #define MAXN 10000+5
 6 using namespace std;
 7 //dp[i][0] : 表示以i为根的子树中的结点与i的最大距离
 8 //dp[i][1] : 表示以i为根的子树中的结点与u的次大距离
 9 //dp[i][2] : 表示i往父亲节点方向走的最大距离 
10 int n,dp[MAXN][3],idx[MAXN];
11 struct Edge{
12     int u,v,w;
13 };
14 vector<Edge> child[MAXN];
15 void dfs1(int now)
16 {
17     if(child[now].size()==0)
18     {
19         dp[now][0]=0;
20         dp[now][1]=0;
21         return;
22     }
23     for(int i=0;i<child[now].size();i++)
24     {
25         Edge edge=child[now][i];
26         int next=edge.v;
27         dfs1(next);
28         if(dp[now][0] < dp[next][0]+edge.w) // ( "其某个孩子的最大"+"其与孩子的距离" ) > "最大" > "次大"
29         {
30             dp[now][1] = dp[now][0];
31             dp[now][0] = dp[next][0] + edge.w;
32             idx[now]=next;
33         }
34         else if(dp[now][1] < dp[next][0]+edge.w) // "最大" > ( "其某个孩子的最大"+"其与孩子的距离" ) > "次大" 
35         {
36             dp[now][1] = dp[next][0]+edge.w;
37         }
38     }
39 }
40 void dfs2(int now)
41 {
42     for(int i=0;i<child[now].size();i++)
43     {
44         Edge edge=child[now][i];
45         int next=edge.v;
46         if(idx[now]==next) dp[next][2] = edge.w + max(dp[now][1],dp[now][2]);
47         else dp[next][2] = edge.w + max(dp[now][0],dp[now][2]);
48         dfs2(next);
49     }
50 }
51 int main()
52 {
53     while(scanf("%d",&n)!=EOF)
54     {
55         for(int i=0;i<=MAXN;i++) child[i].clear();
56         memset(dp,0,sizeof(dp));
57         memset(idx,0,sizeof(idx));
58         for(int i=2;i<=n;i++)
59         {
60             int father,length;
61             scanf("%d%d",&father,&length);
62             child[father].push_back((Edge){father,i,length});
63         }
64         dfs1(1);
65         dfs2(1);
66         for(int i=1;i<=n;i++)
67         {
68             printf("%d\n",max(dp[i][0],dp[i][2]));
69         }
70     }
71 }

 

总的来说,这是一道很不错的树形DP题。

 

HDU 2196 - Computer

标签:href   lan   struct   csdn   name   mem   hdu   com   [1]   

原文地址:http://www.cnblogs.com/dilthey/p/7186556.html

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