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

    大体思路是将一个无根数转化为有根树,再深搜两次,第一次将每个子树的根距其叶子的最远距离求出来(自下而上),第二次求每个节点到其他结点的最远距离(自上而下),但因为在第二次深搜时可能会碰到一个结点的父节点的最远距离经过它,所以我们需要保存一个最长距离和一个次长距离

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define MAXN 10010
    
    int dp[MAXN][2];
    int len[MAXN];
    vector<int> tree[MAXN];
    
    void first_dfs(int src){
        int tree_len = tree[src].size();
        for(int i = 0;i<tree_len;++i){
            int s = tree[src][i];
            first_dfs(s);
            int v = len[s]+dp[s][0];
            dp[src][1] = max(dp[src][1],v > dp[src][0]?dp[src][0]:v);
            dp[src][0] = max(dp[src][0],v);
        }
    }
    
    void second_dfs(int src){
        int tree_len = tree[src].size();
        for(int i = 0;i < tree_len;++i){
            int s = tree[src][i];
            int v = (dp[s][0]+len[s] == dp[src][0]?dp[src][1]:dp[src][0])+ len[s];
            dp[s][1] = max(dp[s][1],v > dp[s][0]?dp[s][0]:v);
            dp[s][0] = max(dp[s][0],v);
            second_dfs(s);
        }
    }
    
    int main(){
        int n;
        while(~scanf("%d",&n)){
            for(int i = 1;i<=n;++i){
                    tree[i].clear();
            }
            memset(dp,0,sizeof(dp));
            int a;
            for(int i = 2;i<=n;++i){
                scanf("%d%d",&a,&len[i]);
                tree[a].push_back(i);
            }
            first_dfs(1);
            second_dfs(1);
            for(int i = 1;i<=n;++i){
                printf("%d
    ",dp[i][0]);
            }
        }
        return 0;
    }
  • 相关阅读:
    idea的svn安装
    工作面板视图
    maven的profile
    web 对接 platform
    jdk动态代理在idea的debug模式下不断刷新tostring方法
    jdk动态代理
    springboot获得应用上下文
    数据库时间日期区别
    Java的date和string互转
    httpclient中文乱码
  • 原文地址:https://www.cnblogs.com/keyi-yin/p/6753243.html
Copyright © 2011-2022 走看看