zoukankan      html  css  js  c++  java
  • hdu2196 树形DP

    题意:
          给你一棵树,求出每一个点到其他点的最大距离.

    思路:

          每个点的最大距离只有两种情况,1是自己忘下面走的最大,二是网上走的最大,取他们的最大便是答案,每个点网下面的最大可以空过dfs直接在回溯的时候求出来,但网上走的呢?往上走其实就是他父亲往上走的最大 和 他父亲往下走最大 中大的那个加上他和她父亲的距离得到的,但是他父亲往下走的最大有可能是他这条路,就是路过他,那么怎么办呢,我们可以再第一遍dfs求最大的时候求出个次大,第二大,当最大的路路过他时那么直接用次大的代替最大,就这样树形dp一边,得到自己网上走的最大,然后输出自己网上走最大和往下走最大中的最优值就行了,具体看代码就懂了,第一遍深搜从下网上,第二遍从上往下...据说还可以用树的直径的性质做,求出树的直径,然后输出max(dis[s] ,dis[t]);自己没试验行不行,不知道时间能不能超时,如果超时我感觉可以用LCA去优化...



    #include<stdio.h>
    #include<string.h>
    
    #define N 11000
                                         
    typedef struct
    {
       int to ,next ,cost;
    }STAR;
    
    STAR E[N];
    
    int list[N] ,tot;
    int maxz[N] ,maxc[N];
    int dp[N] ,mer[N];
    
    void add(int a ,int b ,int c)
    {
       E[++tot].to = b;
       E[tot].cost = c;
       E[tot].next = list[a];
       list[a] = tot;
    }
    
    int maxx(int a ,int b)
    {          
       return a > b ? a : b;
    }
    
    void DFS1(int s)
    {
       int maz = 0 ,mac = 0 ,mk = 0;
       for(int k = list[s] ;k ;k = E[k].next)
       {
          int to = E[k].to;
          mk =  1;
          DFS1(to);
          if(maz <  maxz[to] + E[k].cost)
          {                        
             mer[s] = to;
             mac = maz;
             maz = maxz[to] + E[k].cost;
          } 
          else
          mac = maxx(mac ,maxz[to] + E[k].cost);
       }
       if(mk)
       {
          maxz[s] = maz;
          maxc[s] = mac;
       }
       else maxz[s] = maxc[s] = 0;
    }
    
    void DFS2(int s)
    {
       for(int k = list[s] ;k ; k = E[k].next)
       {
          int to = E[k].to;
          if(to == mer[s])
          dp[to] = maxx(dp[s] ,maxc[s]) + E[k].cost;
          else
          dp[to] = maxx(dp[s] ,maxz[s]) + E[k].cost;
          DFS2(to);
       }
    }
    
    int main ()
    {
       int  n ,i ,a ,b;
       while(~scanf("%d" ,&n))
       {
          memset(list ,0 ,sizeof(list));
          tot = 1;
          for(i = 2 ;i <= n ;i ++)
          {
             scanf("%d %d" ,&a ,&b);
             add(a ,i ,b);
          }
          DFS1(1);
          dp[1] = 0;
          DFS2(1);
          
          for(i = 1 ;i <= n ;i ++)
          printf("%d
    " ,maxx(maxz[i] ,dp[i]));
       }
       return 0;
    } 
                  
    
    

  • 相关阅读:
    筛法“四不像”——《C解毒》试读
    五花八门的main()
    新编《守株待兔》—C语言版—兼聊为什么不应该用%d格式转换输出指针
    含糊之过、多做之过及乱做之过
    怎样调戏程序
    混乱是怎样炼成的——《C解毒》试读
    到处忙活与一劳永逸
    “函数声明”、“函数原型”与“函数定义”辨析
    关于函数原型的对话
    内裤外穿——错位及不伦不类
  • 原文地址:https://www.cnblogs.com/csnd/p/12063266.html
Copyright © 2011-2022 走看看