1. 程式人生 > >HDU 2196 - Computer

HDU 2196 - Computer

details targe 一道 tail ref 第一次 href pan ima

參考來自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