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

    题意:求节点间的最大距离


    先DFS一次 记录下 每一节点的子树下的最大距离(DP[ u ] [ 0 ])和第二大距离(DP[ u ] [ 1 ])

    用DP[ v ] [ 2 ] 表示由v的父节点来的最大距离

    再取DP[ u ] [ 0 ] 与 DP[ u ][ 2 ] 的最值

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    #include <cmath>
    using namespace std;
    #include <queue>
    #include <stack>
    #include <vector>
    #include <deque>
    #include <set>
    #include <map>
    #include <time.h>;
    #define cler(arr, val)    memset(arr, val, sizeof(arr))
    #define FOR(i,a,b)  for(int i=a;i<=b;i++)
    #define IN   freopen ("in.txt" , "r" , stdin);
    #define OUT  freopen ("out.txt" , "w" , stdout);
    typedef long long  LL;
    const int MAXN = 10014;
    const int MAXM = 20014;
    const int INF = 0x3f3f3f3f;
    const int mod = 1000000007;
    struct node
    {
        int v,next;
        LL val;
    } edge[MAXM];
    int head[MAXM],tol;
    LL dp[MAXN][3];
    bool vis[MAXN];
    void init()
    {
        cler(head,-1);
        tol=0;
    }
    void addedge(int u,int v,LL val)
    {
        edge[tol].v=v,edge[tol].val=val,edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].v=u,edge[tol].val=val,edge[tol].next=head[v];
        head[v]=tol++;
    }
    void dfs1(int u)
    {
        if(vis[u]) return ;
        vis[u]=true;
        for(int i=head[u]; ~i; i=edge[i].next)
        {
            int v=edge[i].v;
            if(!vis[v])
            {
                dfs1(v);
                dp[u][1]=max(dp[u][1],dp[v][0]+edge[i].val);
                if(dp[u][1]>dp[u][0])swap(dp[u][1],dp[u][0]);
            }
        }
    }
    void dfs2(int u)
    {
        if(vis[u]) return ;
        vis[u]=true;
        for(int i=head[u]; ~i; i=edge[i].next)
        {
            int v=edge[i].v,val=edge[i].val;
            if(!vis[v])
            {
                if(dp[u][0]>dp[v][0]+val)//dp[u][0]不是由dp[v][0]+val而来的
                    dp[v][2]=max(dp[v][2],max(dp[u][0]+val,dp[u][2]+val));//所以从非v子树来的更长
                else //dp[u][0]由dp[v][0]+val而来的
                    dp[v][2]=max(dp[v][2],max(dp[u][1]+val,dp[u][2]+val));//推断非v子树来的哪个长
                dfs2(v);
            }
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
        int n;
        while(~scanf("%d",&n))
        {
            init();
            for(int i=2; i<=n; i++)
            {
                int a;
                LL b;
                scanf("%d %I64d",&a ,&b );
                addedge(i,a,b);
            }
            cler(vis,false);
            cler(dp,0);
            dfs1(1);
            cler(vis,false);
            dfs2(1);
            for(int i=1;i<=n;i++)
                printf("%I64d
    ",max(dp[i][2],dp[i][0]));
        }
    
    }
    


  • 相关阅读:
    POJ 3126 Prime Path
    POJ 2429 GCD & LCM Inverse
    POJ 2395 Out of Hay
    【Codeforces 105D】 Bag of mice
    【POJ 3071】 Football
    【POJ 2096】 Collecting Bugs
    【CQOI 2009】 余数之和
    【Codeforces 258E】 Devu and Flowers
    【SDOI 2010】 古代猪文
    【BZOJ 2982】 combination
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7091545.html
Copyright © 2011-2022 走看看