• HDU 2196 Computer (树dp)


    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196

    给你n个点,n-1条边,然后给你每条边的权值。输出每个点能对应其他点的最远距离是多少。

    树形dp,2次dfs。

    第一次 dfs1自低向上回溯更新:dp[i][0]表示从底部到i点的最远距离,dp[i][1]则表示次远距离 (dp[i][2]时用到)

        dp[i][0] = max(dp[i][0], dp[i的子节点][0] + edge);

    第二次 dfs2自顶向下顺着更新:dp[i][2]表示从前部到i点的最远距离,顺着下来。

        1)要是dp[i父节点][0]由i点转移 :dp[i][2] = max(dp[i父节点][2] , dp[i父节点][1]) + edge; 

          当然只有一条边的话就:dp[i][2] = dp[i父节点][2];

        2)否则 :dp[i][2] = max(dp[i父节点][2] , dp[i父节点][0]) + edge;

     1 //HDU 2196
     2 //#pragma comment(linker, "/STACK:102400000, 102400000")
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <cstdlib>
     6 #include <cstring>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <ctime>
    11 #include <list>
    12 #include <set>
    13 #include <map>
    14 using namespace std;
    15 typedef long long LL;
    16 typedef pair <int, int> P;
    17 const int N = 1e5 + 5;
    18 struct Edge {
    19     int next, to, cost;
    20 }edge[N << 1];
    21 int dp[N][3], head[N], cnt;
    22 
    23 inline void add(int u, int v, int c) {
    24     edge[cnt].to = v;
    25     edge[cnt].next = head[u];
    26     edge[cnt].cost = c;
    27     head[u] = cnt++;
    28 }
    29 
    30 void dfs1(int u, int p) {
    31     for(int i = head[u]; ~i; i = edge[i].next) {
    32         int v = edge[i].to;
    33         if(v == p)
    34             continue;
    35         dfs1(v, u);
    36         if(edge[i].cost + dp[v][0] >= dp[u][0]) {
    37             dp[u][1] = dp[u][0];
    38             dp[u][0] = dp[v][0] + edge[i].cost;
    39         } else {
    40             dp[u][1] = max(dp[v][0] + edge[i].cost, dp[u][1]);
    41         }
    42     }
    43 }
    44 
    45 void dfs2(int u, int p, int val) {
    46     for(int i = head[u]; ~i; i = edge[i].next) {
    47         int v = edge[i].to;
    48         if(v == p)
    49             continue;
    50         if(dp[u][0] == dp[v][0] + edge[i].cost) {
    51             dp[v][2] = max(dp[u][1], val) + edge[i].cost;
    52         } else {
    53             dp[v][2] = max(dp[u][0], val) + edge[i].cost;
    54         }
    55         dfs2(v, u, dp[v][2]);
    56     }
    57 }
    58 
    59 int main()
    60 {
    61     int n, u, v;
    62     while(~scanf("%d", &n)) {
    63         memset(head, -1, sizeof(head));
    64         cnt = 0;
    65         for(int i = 2; i <= n; ++i) {
    66             scanf("%d %d", &u, &v);
    67             add(i, u, v);
    68             add(u, i, v);
    69         }
    70         memset(dp, 0, sizeof(dp));
    71         dfs1(1, -1);
    72         dfs2(1, -1, 0);
    73         for(int i = 1; i <= n; ++i) {
    74             printf("%d
    ", max(dp[i][0], dp[i][2]));
    75         }
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    【bzoj3083】遥远的国度 树链剖分+线段树
    【bzoj2226】[Spoj 5971] LCMSum 欧拉函数
    xml、json的序列化与反序列化
    什么是安全证书,访问者到底是怎么校验安全证书的,服务端返回安全证书后,客户端再向谁验证呢?
    查看发票组代码后的总结和有感
    网址的正则表达式、常用正则表达式、在线正则表达式检测
    XamlParseException异常
    委托,lambda,匿名方法
    windows中断与共享的连接(samba)
    linux ubuntu 11.04 samba 服务器设置
  • 原文地址:https://www.cnblogs.com/Recoder/p/5821336.html
Copyright © 2020-2023  润新知