zoukankan      html  css  js  c++  java
  • HDOJ树形DP专题之Computer

    题目链接

    题目大意:给定一棵树,对树中每一个结点,求其距其他结点的最远距离。

    分析:最初的想法是对每个结点求一次DFS,那样的话复杂度是O(N2),由于n最大可达10000,所以这个方法肯定会超时。根据树的特殊性可知,每个结点到距其最远的结点,要么通过其儿子结点到达,要么通过其父结点到达,由此想到可用树形动态规划。具体实现时,定义状态df[k],d1[k],d2[k],分别表示结点k通过父结点能到达的最远距离,通过儿子结点能到达的最远距离,通过儿子结点能到达的第二远距离。

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #define MAX(a,b) ((a)>(b)?(a):(b))
     5 #define N 10000
     6 using namespace std;
     7 vector<int> dep[N];
     8 int p[N],d[N],len[N],d1[N],d2[N],df[N],n,dmax;
     9 void dp()
    10 {
    11   int i,j,u,v,tmp;
    12   memset(d1,0,sizeof(d1));
    13   memset(d2,0,sizeof(d2));
    14   for(i=dmax;i>=0;i--)
    15   {
    16     for(j=0;j<dep[i].size();j++)
    17     {
    18       v=dep[i][j];
    19       if(i)
    20       {
    21         u=p[v];
    22         tmp=len[v]-len[u]+d1[v];
    23         if(tmp>=d1[u])  d2[u]=d1[u],d1[u]=tmp;
    24         else if(tmp>=d2[u]) d2[u]=tmp;
    25       }
    26     }
    27   }
    28 }
    29 int dfs(int v)
    30 {
    31   int u,dd;
    32   u=p[v];
    33   if(u==-1)  return df[v]=0;
    34   if(df[v]!=-1) return df[v];
    35   dd=len[v]-len[u];
    36   if(dd+d1[v]==d1[u]) return df[v]=MAX(df[u]+dd,d2[u]+dd);
    37   else  return df[v]=MAX(df[u]+dd,d1[u]+dd); 
    38 }
    39 int main()
    40 {
    41   int i,j,k;
    42   while(~scanf("%d",&n))
    43   {
    44     for(i=0;i<n;i++)  dep[i].clear();
    45     p[0]=-1;
    46     len[0]=dmax=0;
    47     for(i=1;i<n;i++)
    48     {
    49       scanf("%d%d",&j,&k);
    50       p[i]=j-1;
    51       len[i]=len[j-1]+k;
    52       d[i]=d[j-1]+1;
    53       dmax=MAX(dmax,d[i]);
    54       dep[d[i]].push_back(i);
    55     }
    56     dp();
    57     memset(df,-1,sizeof(df));
    58     for(i=0;i<n;i++)
    59     {//printf("%d %d\n",d1[i],d2[i]);
    60       dfs(i);
    61       printf("%d\n",MAX(MAX(d1[i],d2[i]),df[i]));
    62     }
    63   }
    64   return 0;
    65 }
  • 相关阅读:
    java线程的理解
    linux常用命令
    排序算法-(2)-选择排序
    git查看某个文件修改历史
    Information:java: javacTask: 源发行版 1.8 需要目标发行版 1.8
    排序算法-(1)-插入排序
    去重脚本
    771.宝石与石头
    json 的应用
    xml 文件处理
  • 原文地址:https://www.cnblogs.com/algorithms/p/2479526.html
Copyright © 2011-2022 走看看