zoukankan      html  css  js  c++  java
  • HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离

    树形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
    ",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         else
    114         {
    115             dp[v][0]=max(dp[u][0],dp[u][1])+cost[v];
    116         }
    117         dfs3(v,u);
    118     }
    119 }
    View Code
  • 相关阅读:
    openldap---ldapsearch使用
    自旋锁与相互排斥锁之抉择
    探索Android中的Parcel机制(上)
    我的Android开发相关文章
    SoftReference
    Windows7WithSP1/TeamFoundationServer2012update4/SQLServer2012
    机器学习中规则化和模型选择知识
    Java中System的详细用法
    Java中System的详细用法
    Java中System的详细用法
  • 原文地址:https://www.cnblogs.com/-maybe/p/4743949.html
Copyright © 2011-2022 走看看