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

    题目大意:

    每台新电脑都与某一台原电脑相连有一个长度,求每台电脑相距其最远的电脑的距离

    这里因为第一台电脑是最初的,所以可以将第一台电脑作为树根,其他电脑分布就可以形成一棵树

    这里距离有两种,一种是往树底找,一种是往父节点方向走

    第一次dfs记录下每个节点往子节点方向找到其树底的最长距离,第二次dfs记录每个节点如果一开始往父节点方向走所能得到的最大距离

    最后判断两者中得到一个最大值就行了

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 const int N = 10005;
     7 
     8 int first[N] , maxn[N][4] , k , vis[N];
     9 /*
    10 maxn[i][0] 表示i往下到其树底的最长距离,
    11 maxn[i][1]表示到树底的次长距离,
    12 maxn[i][2]表示i节点往上寻找到的最长距离
    13 最后只要比较判断往上找还是往下找能得到的最大距离即可
    14 */
    15 struct Edge{
    16     int y , next , d;
    17 }e[N<<1];
    18 
    19 void add_edge(int x , int y , int d)
    20 {
    21     e[k].y = y , e[k].d = d , e[k].next = first[x];
    22     first[x] = k++;
    23 }
    24 
    25 void my_swap(int &x , int &y)
    26 {
    27     int temp = x;
    28     x = y , y = temp;
    29 }
    30 
    31 void dfs1(int u)
    32 {
    33     vis[u] = 1;
    34     for(int i = first[u] ; i!=-1 ; i=e[i].next){
    35         int v = e[i].y;
    36         if(!vis[v]){
    37             dfs1(v);
    38             //更新次长和最长值,自底向上更新,所以写在dfs后面进行回溯
    39             if(maxn[u][1] < maxn[v][0] + e[i].d){
    40                 maxn[u][1] = maxn[v][0] + e[i].d;
    41                 if(maxn[u][0] < maxn[u][1])
    42                     my_swap(maxn[u][0] , maxn[u][1]);
    43             }
    44         }
    45     }
    46 }
    47 
    48 void dfs2(int u)
    49 {
    50     vis[u] = 1;
    51     for(int i= first[u] ; i!=-1 ; i=e[i].next){
    52         int v = e[i].y;
    53         if(!vis[v]){
    54             //自顶向下更新,所以写在dfs前面
    55             //判断是否最大值落于当前分支
    56             int tmp;
    57             if(maxn[u][0] - maxn[v][0] == e[i].d)
    58                 tmp = maxn[u][1];
    59             else tmp = maxn[u][0];
    60             maxn[v][2] = max(maxn[u][2] , tmp) + e[i].d;
    61             dfs2(v);
    62         }
    63     }
    64 }
    65 
    66 int main()
    67 {
    68    // freopen("a.in" , "r" , stdin);
    69     int n , d , a;
    70     while(scanf("%d" , &n) == 1)
    71     {
    72         k = 0;
    73         memset(first , -1 , sizeof(first));
    74         for(int i=2 ; i<=n ; i++){
    75             scanf("%d%d" , &a , &d);
    76             add_edge(a , i , d);
    77             add_edge(i , a , d);
    78         }
    79 
    80         memset(maxn , 0 , sizeof(maxn));
    81         memset(vis , 0 , sizeof(vis));
    82         dfs1(1);
    83 
    84         memset(vis , 0 , sizeof(vis));
    85         dfs2(1);
    86         /*
    87         for(int i=1 ; i<=n ; i++)
    88             printf("%d %d %d
    " , maxn[i][0] , maxn[i][1] , maxn[i][2]);
    89         */
    90         for(int i=1 ; i<=n ; i++)
    91             printf("%d
    " , max(maxn[i][0] , maxn[i][2]));
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    关键字: simpledateformat24小时 格式串
    浅谈DB2在线分析处理函数
    Java中的final关键字
    TestNG注解使用技巧
    java之静态方法,静态变量
    CssSelector之selenium元素定位
    收藏,常用正则表达式
    正则表达式小结
    [转]java中文乱码的解决
    多叉树结构:JSON数据解析(一)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4230336.html
Copyright © 2011-2022 走看看