zoukankan      html  css  js  c++  java
  • 树形DP——HDU2196

    题目链接

    题目含义

    找出每台电脑距离最远电脑的长度

    题目分析

    对于节点v来说,如果最长长度在它的子树里,我们取dp[u][0]

    否则,最长长度要经过它的父节点u,v的最长长度=dis(u,v)+u的最长长度

    第一种情况,如果u的最长长度经过v这个子节点,那么很明显最长长度不可取,那我们就要去第二长长度dp[u][1]

    第二种情况,如果u的最长长度不经过v这个子节点,那么就取u的最长长度dp[u][0]

    所以每一个节点,都要求子树最长距离dp[u][0],第二长距离dp[u][1]

    为了计算方便,还要求经过父节点的最长距离dp[u][2]

    更详细的过程可以看这个博主的博客

    题目代码

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    using namespace std;
    const int maxn=1e4+7;
    int n,q,a,b,c,tot;
    int head[maxn],dp[maxn][3],longest[maxn];
    struct node{
        int to,w,next;
    }edge[maxn*2];
    void add(int u,int v,int w){
        edge[tot].to=v;
        edge[tot].w=w;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    int dfs1(int u,int fa){
        if(dp[u][0]>=0)return dp[u][0];
        dp[u][0]=dp[u][1]=dp[u][2]=longest[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(v==fa)continue;
            if(dp[u][0]<dfs1(v,u)+edge[i].w){
                dp[u][1]=dp[u][0];
                dp[u][0]=dfs1(v,u)+edge[i].w;
                longest[u]=v;
            }
            else if(dp[u][1]<dfs1(v,u)+edge[i].w){
                dp[u][1]=dfs1(v,u)+edge[i].w;
            }
        }
        return dp[u][0];
    }
    void dfs2(int u,int fa){
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(v==fa)continue;
            if(v==longest[u])dp[v][2]=max(dp[u][1],dp[u][2])+edge[i].w;
            else dp[v][2]=max(dp[u][0],dp[u][2])+edge[i].w;
            dfs2(v,u);
        }
    }
    int main(){
        while(~scanf("%d",&n)){
            tot=0;
            memset(head,-1,sizeof(head));
            memset(dp,-1,sizeof(dp));
            memset(longest,-1,sizeof(longest));
            for(int i=2;i<=n;i++){
                scanf("%d%d",&a,&b);
                add(a,i,b)/*,add(i,a,b)*/;
            }
            dfs1(1,0);
            dfs2(1,0);
            for(int i=1;i<=n;i++)
                printf("%d
    ",max(dp[i][0],dp[i][2]));
        }
        return 0;
    }
  • 相关阅读:
    vue2.0路由-适合刚接触新手简单理解
    JAVA实现DES加密实现详解
    计算机网络: IP地址,子网掩码,网段表示法,默认网关,DNS服务器详解
    vue-自定义组件传
    mybatis 乐观锁和逻辑删除
    axios 全攻略之基本介绍与使用(GET 与 POST)
    PowerDesigner使用教程
    scala slick mysql utf8mb4 支持
    spring-boot jpa mysql emoji utfmb4 异常处理
    花生壳的ddns 关键时刻又掉链子,准备迁到阿里万网
  • 原文地址:https://www.cnblogs.com/helman/p/11273176.html
Copyright © 2011-2022 走看看