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

    链接:http://acm.hdu.edu.cn/showproblem.php?

    pid=2196

    题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问每台电脑和其它电脑的最远距离是多少。

    思路:这是一道树形DP的经典题目。须要两次DFS,第一次DFS找到树上全部的节点在不同子树中的最远距离和次远的距离(在递归中进行动态规划就可以),第二次DFS从根向下更新出终于答案。对于每次更新到的节点u,他的最远距离可能是来自u的子树,或者是u的父亲节点的最远距离。假设u的父亲节点的最远距离是在第一次DFS过程中更新自u的话,那么u的最远距离就不能更新自u的父亲节点的最远节点,而是有可能更新自u的父亲节点的次远距离,这就是每次更新时要记录节点的次远距离的原因。

    代码:

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <ctype.h>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <set>
    #include <stack>
    #include <string>
    #include <vector>
    #define eps 1e-8
    #define INF 0x7fffffff
    #define maxn 10005
    #define PI acos(-1.0)
    #define seed 31//131,1313
    typedef long long LL;
    typedef unsigned long long ULL;
    using namespace std;
    int dp[maxn][2],from[maxn],head[maxn],top;
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(dp,0,sizeof(dp));
        top=0;
    }
    struct Edge
    {
        int v,w;
        int next;
    } edge[maxn*2];
    void add_edge(int u,int v,int w)
    {
        edge[top].v=v;
        edge[top].w=w;
        edge[top].next=head[u];
        head[u]=top++;
    }
    void dfs_first(int u,int f)
    {
        from[u]=u;
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v,w=edge[i].w;
            if(v==f)
                continue;
            dfs_first(v,u);
            if(dp[v][0]+w>dp[u][0])
            {
                from[u]=v;
                dp[u][1]=dp[u][0];
                dp[u][0]=dp[v][0]+w;
            }
            else if(dp[v][0]+w>dp[u][1])
                dp[u][1]=dp[v][0]+w;
        }
    }
    void dfs_second(int u,int f,int k)
    {
        if(u!=f)
            if(from[f]!=u)
            {
                if(dp[f][0]+k>dp[u][0])
                {
                    from[u]=f;
                    dp[u][1]=dp[u][0];
                    dp[u][0]=dp[f][0]+k;
                }
                else if(dp[f][0]+k>dp[u][1])
                    dp[u][1]=dp[f][0]+k;
            }
            else
            {
                if(dp[f][1]+k>dp[u][0])
                {
                    from[u]=f;
                    dp[u][1]=dp[u][0];
                    dp[u][0]=dp[f][1]+k;
                }
                else if(dp[f][1]+k>dp[u][1])
                    dp[u][1]=dp[f][1]+k;
            }
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v,w=edge[i].w;
            if(v==f)
                continue;
            dfs_second(v,u,w);
        }
    }
    int main()
    {
        int T,v,w;
        while(~scanf("%d",&T))
        {
            init();
            for(int i=2; i<=T; i++)
            {
                scanf("%d%d",&v,&w);
                add_edge(v,i,w);
                add_edge(i,v,w);
            }
            dfs_first(1,1);
            dfs_second(1,1,0);
            for(int i=1;i<=T;i++)
                printf("%d
    ",dp[i][0]);
        }
        return 0;
    }
    


  • 相关阅读:
    windwos8.1英文版安装SQL2008 R2中断停止的解决方案
    indwows8.1 英文版64位安装数据库时出现The ENU localization is not supported by this SQL Server media
    Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds
    SQL数据附加问题
    eclipse,myeclipse中集合svn的方法
    JAVA SSH 框架介绍
    SSH框架-相关知识点
    SuperMapRealSpace Heading Tilt Roll的理解
    SuperMap iserver manage不能访问本地目的(IE9)
    Myeclipse中js文件中的乱码处理
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7082650.html
Copyright © 2011-2022 走看看