• 树形DP入门之HDU 1296


                                HDU 2196 Computer 

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196

    题目大意:给你一颗树,求树上一节点到其他节点的最远距离。

    输入:一个整数N代表有N个节点,然后N-1(从第二行到第N行)行,每行两个数字a,b代表第a台电脑和第i台电脑连接的长度。

    输出:每个节点到其他节点的最远距离

    此题需要两次dfs,一次算出他到子节点的最大距离,另一次算出他父亲走过的最远距离加上他和父亲之间的距离。而每个节点到子节点的距离需要存储第一大和第二大。因为如果只存最大值的话,判断一个点的从父节点过来的最大值,

    那么如果他的父节点存的最大值正好是从该点过来的,那么就失去了从父节点过来的状态,所以要记录最大的两个值。

    对于一个节点i dp[i][0]表示从子节点的最大值,显示这是一种可能的答案

    dp[i][2]表示从父亲节点过来的最大值

    1. dp[2][v] = max( dp[0][u]+weight(u,v) , dp[2][u]+weight(u,v) ) (v是u的儿子 且 u往下走的最远距离不经过v)
    2. dp[2][v] = max( dp[1][u]+weight(u,v) , dp[2][u]+weight(u,v) ) (v是u的儿子 且 u往下走的最远距离经过v)

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 10000+50
    int dp[maxn][3];
    struct node
    {
        int to;
        int val;
        int next;
    }edge[maxn*2];
    int head[maxn],tot,n;
    void init()
    {
          for(int i=1;i<=n;i++)
          {
              head[i]=-1;
          }
          tot=0;
          memset(edge,0,sizeof(edge));
    }
    void add(int u,int v,int w)
    {
        edge[tot].to=v;
        edge[tot].val=w;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void dfs1(int u)
    {
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            dfs1(v);
            int w=edge[i].val;
            int temp=dp[v][0]+w;
            if(temp>=dp[u][0])
            {
                dp[u][1]=dp[u][0];
                dp[u][0]=temp;
            }
            else if(temp>dp[u][1]) dp[u][1]=temp;
        }
    }
    void dfs2(int u)
    {
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
             if(dp[u][0]==dp[v][0]+edge[i].val)
             {
                 dp[v][2]=max(dp[u][2],dp[u][1])+edge[i].val;
             }
             else
             {
                 dp[v][2]=max(dp[u][2],dp[u][0])+edge[i].val;
             }
             dfs2(v);
        }
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            init();
            for(int i=2;i<=n;i++)
            {
                int a,b;
                cin>>a>>b;
                add(a,i,b);
            }
            memset(dp,0,sizeof(dp));
            dfs1(1);
            dfs2(1);
            for(int i=1;i<=n;i++) printf("%d
    ",max(dp[i][0],dp[i][2]));
        }
        return 0;
    }
  • 相关阅读:
    win10安装scrapy
    win10安装 pandas
    scrapy 启动失败,scrapy startproject test 出错 'module' object has no attribute 'OP_NO_TLSv1_1
    Mac环境下安装运行splash
    通过软链接解决目录空间不足的问题
    CentOS 图形界面的关闭与开启
    shell+crontab 实时服务进程监控重启
    Linux下查看yun rpm dpkg 软件是否安装成功的方法
    ubuntu设置root登录ssh
    Ubuntu的中文乱码问题
  • 原文地址:https://www.cnblogs.com/tombraider-shadow/p/11170646.html
Copyright © 2020-2023  润新知