zoukankan      html  css  js  c++  java
  • HDU_2196 Computer (树型dp)

      纠结的问题。做了两天,还是在拜读大牛代码的情况下ac的。好好谢谢总结吧。

      诸位大牛的思路是两次dfs。前提:建树的时候按无向边从上往下建。第一次dfs是搜出一个根结点到其他结点的最长路径和次长路径(次长路径不是最长路径的子路径,也就是说不在同一条路上。)

      一个结点到其他结点的最长路径怎么得到?1、可能是从这个结点往下取到最长路径。2、可能是从这个结点的父结点上选去另一条路径。

      当情况一时:第一次dfs所得的最长路径就是要求的结果。当情况二时:第一次dfs所得的次长路径就是所求结果。

      另外,因为是无向边建树,所以第一次dfs从下往上搜,第二次dfs从上往下搜。

      具体实现:定义dp[i]表示i到其他结点的最长路径。 f[i]表示从i结点到他的子结点的最长路径 l[i]表示i到其子结点的次长路径。 dir[i]表示最长路径所在的方向,防止最长路径跟次长路径重复。

    核心代码:

    void dfs_0(int r) {
    if(f[r]) return ;
    int len = g[r].size();
    if(len == 0) return ;
    int i, max = -1, flag = -1, flag1 = -1, c;
    for(i = 0; i < len; i++) {
    c = g[r][i].c;
    dfs_0(c);
    if(f[c] + g[r][i].val > max) {
    max = f[c] + g[r][i].val;
    flag = i;
    }
    }
    f[r] = max;
    dir[r] = flag;
    max = -1;
    for(i = 0; i < len; i++) {
    c = g[r][i].c;
    if(f[c] + g[r][i].val > max && i != flag) {
    max = f[c] + g[r][i].val;
    flag1 = i;
    }
    }
    if(flag1 != -1) l[r] = max;
    }

    void dfs_1(int r) {
    int i, len, c;
    len = g[r].size();
    for(i = 0; i < len; i++) {
    c = g[r][i].c;
    if(i == dir[r])
    dp[c] = max(dp[r], l[r]) + g[r][i].val;
    else
    dp[c] = max(dp[r], f[r]) + g[r][i].val;
    dfs_1(c);
    }
    }

    ps:因为可能出现整颗树只有一条边的情况,所以输出结果时取f[i] 和dp[i]的最大。

  • 相关阅读:
    多语言网站(如何实现网站的多语言版本?)
    宝塔linux面板.txt
    什么是海外镜像点?
    一步一步CCNA之三:路由器全局配置模式
    Kmeans算法 与 KNN算法
    新浪公开课
    shanghaiR
    Announcing Couch Crawler, a CouchDB search engine/crawler
    字符串相似度算法(编辑距离算法 Levenshtein Distance)
    R与SAS、SPSS的比较
  • 原文地址:https://www.cnblogs.com/vongang/p/2315859.html
Copyright © 2011-2022 走看看