• 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
    ", mx[i]);
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    bzoj3675 [Apio2014]序列分割
    bzoj4010 [HNOI2015]菜肴制作
    bzoj4011 [HNOI2015]落忆枫音
    bzoj100题
    JSP—内置对象
    集合框架—常用的map集合
    集合框架—HashMap
    集合框架—代码—用各种集合进行排序
    集合框架—2种排序比较器
    array
  • 原文地址:https://www.cnblogs.com/bfshm/p/3953877.html
Copyright © 2020-2023  润新知