hdu 2196 Computer

题目大意

给你一颗边带权值的树,求树上的每一点距离其最远的一个点的距离

分析

经典的树形DP题。由于对于一个节点来说,可能得到的距离最大的值的路径来自他的子树,或者从他的父节点过来,所以用两次DFS。

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

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<string>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<set>
  8 #define MAXN 20010
  9 using namespace std;
 10 struct Node
 11 {
 12     int v,w;
 13     int next;
 14 }node[MAXN];
 15 int tot,n;
 16 int head[MAXN],maxn[MAXN],smaxn[MAXN],maxid[MAXN],smaxid[MAXN];
 17 void add(int u,int v,int w)
 18 {
 19     node[tot].v=v;
 20     node[tot].w=w;
 21     node[tot].next=head[u];
 22     head[u]=tot;
 23     tot++;
 24 }
 25 void dfs1(int u,int p)
 26 {
 27     maxn[u]=0;
 28     smaxn[u]=0;
 29     for(int i=head[u];i!=-1;i=node[i].next)
 30     {
 31         int v=node[i].v;
 32         if(v==p)
 33             continue;
 34         dfs1(v,u);
 35         if(smaxn[u]<maxn[v]+node[i].w)
 36         {
 37             smaxn[u]=maxn[v]+node[i].w;
 38             smaxid[u]=v;
 39             if(smaxn[u]>maxn[u])
 40             {
 41                 swap(smaxn[u],maxn[u]);
 42                 swap(smaxid[u],maxid[u]);
 43             }
 44         }
 45     }
 46 }
 47 void dfs2(int u,int p)
 48 {
 49     for(int i=head[u];i!=-1;i=node[i].next)
 50     {
 51         int v=node[i].v;
 52         if(v==p)
 53             continue;
 54         if(v==maxid[u])
 55         {
 56             if(node[i].w+smaxn[u]>smaxn[v])
 57             {
 58 
 59                 smaxn[v]=node[i].w+smaxn[u];
 60                 smaxid[v]=u;
 61                 if(smaxn[v]>maxn[v])
 62                 {
 63                     swap(smaxn[v],maxn[v]);
 64                     swap(smaxid[v],maxid[v]);
 65                 }
 66             }
 67         }
 68         else
 69         {
 70             if(node[i].w+maxn[u]>smaxn[v])
 71             {
 72                 smaxn[v]=node[i].w+maxn[u];
 73                 smaxid[v]=u;
 74                 if(smaxn[v]>maxn[v])
 75                 {
 76                     swap(smaxn[v],maxn[v]);
 77                     swap(maxid[v],smaxid[v]);
 78                 }
 79             }
 80         }
 81         dfs2(v,u);
 82 
 83     }
 84 }
 85 int main()
 86 {
 87     while(scanf("%d",&n)!=EOF)
 88     {
 89         tot=0;
 90         int v,w;
 91         memset(head,-1,sizeof(head));
 92         for(int i=2;i<=n;i++)
 93         {
 94             scanf("%d %d",&v,&w);
 95             add(i,v,w);
 96             add(v,i,w);
 97         }
 98         dfs1(1,-1);
 99         dfs2(1,-1);
100         for(int i=1;i<=n;i++)
101             printf("%d\n",maxn[i]);
102 
103     }
104     return 0;
105 }

 

图是用邻接表保存的,不理解的可以看看我的上一篇博客

 

posted on 2015-04-23 22:44  tsw123  阅读(141)  评论(0编辑  收藏  举报

导航