HDU 2196:Computer 树形DP

Computer

题目链接:

http://acm.hdu.edu.cn/submit.php?pid=2196

题意:

学校里有一台电脑(编号为1),这些年来又陆续买了(N-1)台电脑,每一台新电脑都要和一台已经存在的电脑连接,构成了一棵以1为根的树,求树上每个节点到所有叶子节点的距离的最大值。

题解:

 先跑一遍DFS记录下val1(“以V为根的子树”的最远叶子节点的距离)和val2(与路径[V到其最远叶子节点]没有公共路径的最远的叶子节点的距离)

可以发现 当前节点V到其他所有点的最大值可能由三种情况得到:

  ①其父亲节点Fa到以“Fa为根的子树”的最远叶子节点的距离val1(注意这里,当这个最远节点同时也是V的最远节点时不可取,应取Fa对应的val2)+Fa到V的边权

    ②当前节点到其下的叶子节点的最大距离val1

  ③其父亲节点Fa到除了“以Fa为根的子树”上的节点外  最远的节点的距离(设其为fa)+Fa到V的边权

可以知道①和②的答案都已经在第一次的DFS中求出来了,要求的就是③的值

再进行一遍DFS,即可得到答案

             

代码

#include<stdio.h>
#include<vector>
using namespace std;
const int N=10001;
struct edge
{
  int to,val;
  edge(int x=0,int y=0)
  {
    to=x,val=y;
  }
};
int mmax(int a,int b,int c)
{
  return a>b?(a>c?a:c):(b>c?b:c);
}
vector<edge>q[N];
struct node
{
  int value,fa,val1,val2,son1,son2;
}t[N];
void Dfs_Findval(int id)
{
  int m=1,son1,son2;
  for(int i=0;i<q[id].size();++i)
  {
    int to=q[id][i].to;
    Dfs_Findval(to);
    int val=q[id][i].val+t[to].val1;
    int son=t[to].son1;
    if(val>t[id].val1)
    {
      t[id].val2=t[id].val1;
      t[id].son2=t[id].son1;
      t[id].val1=val;
      t[id].son1=son;
    }
    else if(val>t[id].val2)
     {
      t[id].val2=val;
      t[id].son2=son;
    }
    m=0;
  }
  if(m)t[id].son1=t[id].son2=id;
  return ;
}
void Dfs_Findans(int id)
{
  for(int i=0;i<q[id].size();++i)
  {
    int to=q[id][i].to;
    int V=q[id][i].val;
    if(t[to].son1!=t[id].son1)
    {
      t[to].fa=mmax(t[id].val1+V,t[id].fa+V,0);
      t[to].value=mmax(t[to].val1,t[id].fa+V,t[id].val1+V);
    }
    else
    {
      t[to].fa=mmax(t[id].val2+V,t[id].fa+V,0);
      t[to].value=mmax(t[to].val1,t[id].fa+V,t[id].val2+V);
    }
    Dfs_Findans(to);
  }
}
void solve()
{
  int n,x,y;
  while(~scanf("%d",&n))
  {
    for(int i=1;i<=n;++i)
    {
      q[i].clear();
      t[i].val1=t[i].val2=t[i].fa=0;
    }
    for(int i=2;i<=n;++i)
    {
      scanf("%d%d",&x,&y);
      q[x].push_back(edge(i,y));
    }
    Dfs_Findval(1);
    Dfs_Findans(1);
    printf("%d ",t[1].val1);
    for(int i=2;i<=n;++i)
    printf("%d ",t[i].value);
  }
}
int main()
{
  solve();
}

  

原文地址:https://www.cnblogs.com/kiuhghcsc/p/5592190.html