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

    想法:对于一棵树,对于任意一个节点,它的最大值可以来自以它为根的子树,也可以来自它的父亲。
    所以需要考虑二个方向的情况。所以必须考虑2个方向。
    解法:dp[i][0]保存子树的值,dp[i][1]保存父亲结点方向+dis[i,root];
    可以先一遍dfs,保存任意点子树的最大值,同时保存任意点取最大值的方向,同时维护他的第二大值。
    然后进行第二次dfs,对于结点u,如果它的孩子不是它取最大值路径上的点,那么孩子的值dp[i][1]为
    max(dp[root][1], dp[root][0])+ dis[i,root];不然dp[i][1]为父亲结点的第二大值 + dis[i,root];
    然后第二大值为dp[i][1];

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int MAXN = 10010;
    struct node
    {
        int to;
        int v;
        int next;
    }edge[MAXN*3];
    int pre[MAXN],index,vis[MAXN],n;
    int dp[MAXN][2],way[MAXN],sv[MAXN];
    //sv[]存第另一边的 不是子树的 way[]表示当前点最大值从哪里来
    //dp[][0]表示子树方向的最大值 dp[][1]表示另一方向的最大值
    int max(int x,int y){
        return x>y?x:y;
    }
    int min(int x,int y){
        return x<y?x:y;
    }
    void add(int x,int y,int z)
    {
        edge[index].to = y;
        edge[index].v = z;
        edge[index].next = pre[x];
        pre[x] = index++;
    }
    void dfs1(int root)
    {
        vis[root] = 1;
        int i;
        int set = root;
        for(i=pre[root]; i!=-1; i=edge[i].next){
            int t = edge[i].to;
            if(!vis[t]){
                dfs1(t);
                if(dp[root][0] > dp[t][0] + edge[i].v){
                    sv[root] = max(sv[root], dp[t][0] + edge[i].v);
                }
                else {
                    set = t;
                    sv[root] = dp[root][0];
                    dp[root][0] = dp[t][0] + edge[i].v;
                }
            }
        }
        way[root] = set;
    }
    void dfs2(int root)
    {
        vis[root] = 1;
        int i;
        for(i=pre[root]; i!=-1; i=edge[i].next){
            int t = edge[i].to;
            if(!vis[t]){
                if(way[root] != t){
                    dp[t][1] = max(dp[root][0], dp[root][1]) + edge[i].v;
                    sv[t] = dp[t][1];
                }
                else {
                    dp[t][1] = sv[root] + edge[i].v;
                    sv[t] = dp[t][1];
                }
                dfs2(t);
            }
        }
    }
    int main()
    {
        int i;
        while(~scanf("%d",&n))
        {
            index = 1;
            memset(sv,0,sizeof(sv));
            memset(dp,0,sizeof(dp));
            memset(pre,-1,sizeof(pre));
            for(i=2; i<=n; ++i){
                int x,v;
                scanf("%d %d",&x, &v);
                add(i, x, v);
                add(x, i, v);
            }
            memset(vis,0,sizeof(vis));
            dfs1(1);
            /*for(i=1; i<=n; i++){
                printf("%d  ",sv[i]);
            }
            cout<<endl;*/
            memset(vis,0,sizeof(vis));
            dfs2(1);
            for(i=1; i<=n; i++){
                printf("%d
    ",max(dp[i][0],dp[i][1]));
            }
        }
    }
    /*
    7
    1 1
    1 1
    2 1
    2 1
    3 1
    3 1
    8
    1 1
    1 1
    2 1
    2 1
    3 1
    5 1
    7 1
    */
  • 相关阅读:
    48. Rotate Image
    83. Remove Duplicates from Sorted List
    46. Permutations
    HTML5笔记
    18. 4Sum
    24. Swap Nodes in Pairs
    42. Trapping Rain Water
    Python modf() 函数
    Python min() 函数
    Python max() 函数
  • 原文地址:https://www.cnblogs.com/sweat123/p/5020312.html
Copyright © 2011-2022 走看看