树形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\n",max(dp[i][0],dp[i][2]));
    }
    return 0;
}

 

posted @ 2019-07-11 16:07  mcalex  阅读(188)  评论(0编辑  收藏  举报