• 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;
    }
  • 相关阅读:
    Hibernate缓存策略
    Hibernate初探之一对多映射 及 myeclipse自动生成hibernate文件方法
    Hibernate初探之单表映射
    01箱包问题
    oracle备份恢复
    旅游参考
    Linux中find常见用法示例
    oracle 比较两个用户表结构的区别。
    SSH自动断开连接的原因
    在Oracle中查看客户端连接的IP信息 .
  • 原文地址:https://www.cnblogs.com/keyi-yin/p/6753243.html
Copyright © 2020-2023  润新知