1. 程式人生 > >HDU 2196 Computer(經典樹形DP)

HDU 2196 Computer(經典樹形DP)

hdu space const include name style 就是 std cstring

題意自己看(猜)

題解

這題很經典,就是記錄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 }

HDU 2196 Computer(經典樹形DP)