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]));
        }
    
    }
    


  • 相关阅读:
    jmeter之正则表达式
    python_appium搭建APP自动化测试环境
    网络编程
    四种单例模式
    Pycharm快捷键
    面向对象
    阶段性总结
    模块之numpy,pandas,matplotlib
    模块之json,pickle,os,sys,logging
    模块之Time,datatime,hashlib,hmac
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7091545.html
Copyright © 2011-2022 走看看