HDU 2196 Computer (树形dp)

题目链接

题意:就是给你一棵树,每条边都有一定的权值,然后让你找到每个点所能走到的最远距离

分析:

这个题还是有点晕,贴一下大神的分析,分析的很透彻

先以 1 作为根节点进行一次 dfs 遍历,遍历的时候把以 第 i 为根节点往子树方向可以走到的最远距离和次远距离给求出来,且这两个距离是不在同一个分支中的
然后我们进行第二次的从根节点开始dfs遍历,这时候我们要判断的是对于一个节点 i ,除了子树方向上可能有最远距离外,我通过父节点方向是否可以有更加远的距离
 
,而对于这个操作,我们只要访问父节点所能到达的最远距离,然后接上一段就行了,但是这里会产生一个问题——就是父节点的最远距离可能是会经过当前这个节点
 
的,因此我们要进行判断当前节点是否在父节点的最远距离的分支上
如果在的话,那么我们要换一个分支,且要是最远的,这个其实就是第一次dfs中求出的与最远路径不在同一分支上的次远路径,我们接上这段进行转移
如果不在的话,那么我们直接接上父节点的最远路径进行转移就行了
 
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <algorithm>
  7 #define LL __int64
  8 const int maxn = 10000+10;
  9 using namespace std;
 10 int t;
 11 struct node
 12 {
 13     int v, w, ne;
 14 }p[2*maxn];
 15 int head[2*maxn];
 16 int mx[maxn], tmx[maxn], mxid[maxn], tmxid[maxn];
 17 
 18 void init()
 19 {
 20     t = 0;
 21     memset(head, -1, sizeof(head));
 22 }
 23 void add(int u, int v, int w)
 24 {
 25     p[t].v = v;
 26     p[t].w = w;
 27     p[t].ne = head[u];
 28     head[u] = t;
 29     t ++;
 30 }
 31 void dfs1(int u, int pre)
 32 {
 33     int i;
 34     mx[u] = 0;
 35     tmx[u] = 0;
 36     for(i = head[u]; i != -1; i = p[i].ne)
 37     {
 38         int v = p[i].v;
 39         if(v==pre) continue;  //因为是无向图,所以要防止往回走
 40         dfs1(v, u);
 41         if(tmx[u] < mx[v]+p[i].w)
 42         {
 43             tmx[u] = mx[v]+p[i].w;
 44             tmxid[u] = v;
 45             if(tmx[u] > mx[u])
 46             {
 47                 swap(mx[u], tmx[u]);
 48                 swap(mxid[u], tmxid[u]);
 49             }
 50         }
 51     }
 52 }
 53 void dfs2(int u, int pre)
 54 {
 55     int i;
 56     for(i = head[u]; i != -1; i = p[i].ne)
 57     {
 58         int v = p[i].v;
 59         if(v==pre) continue;
 60         if(v==mxid[u])
 61         {
 62             if(p[i].w+tmx[u]>tmx[v])
 63             {
 64                 tmx[v] = tmx[u]+p[i].w;
 65                 tmxid[v] = u;
 66                 if(tmx[v]>mx[v])
 67                 {
 68                     swap(tmx[v], mx[v]);
 69                     swap(tmxid[v], mxid[v]);
 70                 }
 71             }
 72         }
 73         else
 74         {
 75             if(p[i].w+mx[u]>tmx[v])
 76             {
 77                 tmx[v] = p[i].w+mx[u];
 78                 tmxid[v] = u;
 79                 if(tmx[v] > mx[v])
 80                 {
 81                    swap(tmx[v], mx[v]);
 82                    swap(tmxid[v], mxid[v]);
 83                 }
 84             }
 85         }
 86         dfs2(v, u);
 87     }
 88 }
 89 int main()
 90 {
 91     int n, i, u, v, w;
 92     while(~scanf("%d", &n))
 93     {
 94         init();
 95         for(u = 2; u <= n; u++)
 96         {
 97             scanf("%d%d", &v, &w);
 98             add(u, v, w);
 99             add(v, u, w);
100         }
101         dfs1(1, -1);
102         dfs2(1, -1);
103         for(i = 1; i <= n; i++)
104         printf("%d\n", mx[i]);
105     }
106     return 0;
107 }

 

posted @ 2014-09-03 15:51  水门  阅读(168)  评论(0编辑  收藏  举报