HDU 2196 Computer 樹形DP 經典題

來源:互聯網
上載者:User

標籤:

給出一棵樹,邊有權值,求出離每一個節點最遠的點的距離

 

樹形DP,經典題

本來這道題是無根樹,可以隨意選擇root,

但是根據輸入資料的方式,選擇root=1明顯可以方便很多。

我們先把邊權轉化為點權,放在數組cost中

令tree(i)表示以節點i為根的子樹

對於節點i,離該節點最遠的點要不就是在tree(i)中,要不就是在father(i)上面

令:

dp[i][1] : 在子樹tree(i)中,離i最遠的距離

dp[i][2] : 在子樹tree(i)中,離i第二遠的距離 (遞推的時候需要)

dp[i][0] : 在樹tree(root)-tree(i)中,離i最遠的距離

son[i] : 在子樹tree(i)中,離i最遠的點是在tree(son[i])中,即最遠路徑經過節點son[i]

 

則對於每一個i,離i最遠的距離=max(dp[i][0],dp[i][1])

 

流程:

0.鏈式前向星建樹

1.dfs1,確定dp[i][1]

2.dfs2,確定dp[i][2]

dfs1和dfs2都很簡單

3.dfs3,遞推確定dp[i][0]

 

 

  1 #include<cstdio>  2 #include<cstring>  3   4 using namespace std;  5   6 const int maxn=10000+5;  7 const int inf=0x3f3f3f3f;  8   9 inline int max(int a,int b) 10 { 11     return a>b?a:b; 12 } 13  14 struct Edge 15 { 16     int to,next; 17 }; 18 Edge edge[maxn]; 19 int head[maxn]; 20 int tot; 21 int cost[maxn]; 22 int son[maxn]; 23 int dp[maxn][3]; 24  25 void init() 26 { 27     memset(head,-1,sizeof head); 28     tot=0; 29     memset(dp,0,sizeof dp); 30     memset(son,-1,sizeof son); 31 } 32  33 void addedge(int u,int v) 34 { 35     edge[tot].to=v; 36     edge[tot].next=head[u]; 37     head[u]=tot++; 38 } 39  40 void solve(int n); 41 void dfs1(int u,int pre); 42 void dfs2(int u,int pre); 43 void dfs3(int u,int pre); 44  45 int main() 46 { 47     int n; 48     while(~scanf("%d",&n)) 49     { 50         init(); 51         cost[1]=0; 52         for(int i=2;i<=n;i++) 53         { 54             int u; 55             scanf("%d %d",&u,&cost[i]); 56             addedge(u,i); 57         } 58         solve(n); 59     } 60     return 0; 61 } 62  63 void solve(int n) 64 { 65     dfs1(1,-1); 66     dfs2(1,-1); 67     dp[1][0]=0; 68     dfs3(1,-1); 69  70     for(int i=1;i<=n;i++) 71     { 72         printf("%d\n",max(dp[i][0],dp[i][1])); 73     } 74     return ; 75 } 76  77 void dfs1(int u,int pre) 78 { 79     for(int i=head[u];~i;i=edge[i].next) 80     { 81         int v=edge[i].to; 82         dfs1(v,u); 83         if(dp[v][1]+cost[v]>dp[u][1]) 84         { 85             dp[u][1]=dp[v][1]+cost[v]; 86             son[u]=v; 87         } 88     } 89 } 90  91 void dfs2(int u,int pre) 92 { 93     for(int i=head[u];~i;i=edge[i].next) 94     { 95         int v=edge[i].to; 96         dfs2(v,u); 97         if(v==son[u]) 98             continue; 99         if(dp[v][1]+cost[v]>dp[u][2])100             dp[u][2]=dp[v][1]+cost[v];101     }102 }103 104 void dfs3(int u,int pre)105 {106     for(int i=head[u];~i;i=edge[i].next)107     {108         int v=edge[i].to;109         if(v==son[u])110         {111             dp[v][0]=max(dp[u][0],dp[u][2])+cost[v];112         }113         else114         {115             dp[v][0]=max(dp[u][0],dp[u][1])+cost[v];116         }117         dfs3(v,u);118     }119 }
View Code

 

HDU 2196 Computer 樹形DP 經典題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.