HDU 2196 Computer(经典树形DP)

题意自己看(猜)

题解

这题很经典,就是记录dp[i][0/1/2]分别代表,从i点向下最大和次大深度,和向上最大深度。

然后转移就行了。

我的写法可能太丑了。死活调不出来,写了一个漂亮的

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=10010;
 8 int dp[N][5],cnt,head[N],longest[N],n;
 9 struct edge{
10     int to,nxt,w;
11 }e[N*2];
12 void add(int u,int v,int w){
13     cnt++;
14     e[cnt].nxt=head[u];
15     e[cnt].to=v;
16     e[cnt].w=w;
17     head[u]=cnt;
18 }
19 void dfs1(int u,int fa){
20     for(int i=head[u];i;i=e[i].nxt){
21         int v=e[i].to;
22         if(v==fa)continue;
23         dfs1(v,u);
24         if(dp[v][0]+e[i].w>dp[u][0]){
25             longest[u]=v;
26             dp[u][1]=dp[u][0];
27             dp[u][0]=dp[v][0]+e[i].w;
28         }
29         else if(dp[v][0]+e[i].w>dp[u][1]){
30             dp[u][1]=dp[v][0]+e[i].w;
31         }
32     }
33 }
34 void dfs2(int u,int fa){
35     for(int i=head[u];i;i=e[i].nxt){
36         int v=e[i].to;
37         if(v==fa)continue;
38         if(v==longest[u])dp[v][2]=max(dp[u][2],dp[u][1])+e[i].w;
39         else dp[v][2]=max(dp[u][2],dp[u][0])+e[i].w;
40         dfs2(v,u);
41     }
42 }
43 int main(){
44     while(scanf("%d",&n)!=EOF){
45         memset(head,0,sizeof(head));
46         cnt=0;
47         memset(dp,0,sizeof(dp));
48         memset(longest,0,sizeof(longest));
49         for(int i=2;i<=n;i++){
50             int f,w;
51             scanf("%d%d",&f,&w);
52             add(f,i,w);add(i,f,w);
53         } 
54         dfs1(1,0);
55         dfs2(1,0);
56         for(int i=1;i<=n;i++){
57             printf("%d\n",max(dp[i][0],dp[i][2]));
58         }
59     }
60     return 0;
61 }

猜你喜欢

转载自www.cnblogs.com/Xu-daxia/p/9748084.html