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 }