zoukankan      html  css  js  c++  java
  • hdu 2196 computer 树状dp

    Computer

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3731    Accepted Submission(s): 1886


    Problem Description

    A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.


    Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
     

    Input

    Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.
     

    Output

    For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).
     

    Sample Input

    5
    1 1
    2 1
    3 1
    1 1
     

    Sample Output

    3
    2
    3
    4
    4
     
    有一个计算机组成的无向树状网络,要求求出每台计算机到其他计算机的最大距离。
    原先有1号计算机,在此之后没加如一台计算机都与原有的一台计算机连接,并有距离c。题中数据较大,所以不能对每个节点进行递归求深度。仔细想想,在以1号计算机为根节点的情况下,每个节点的最大距离来自其父节点或其子节点。
    来自子节点的情况比较简单,我们只要对其求深度就行maxn[t] = max(maxn[ti] + l[ti][fa])。
    而父节点就要分情况,对于求的t节点,其父节点为fa节点,若fa节点的最大距离不是经过t节点来的,那么t节点的最大距离就是max(maxn[t], maxn[fa] + l[t][fa]);如果是经过t节点来的,那依然可以从fa节点过来,不过路径不是最大距离那条而是次大距离那条——second_maxn[fa], max(maxn[t], second_max[fa] + l[t][fa]);因此,在记录最大距离的同时也要记入次大距离。
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int INF = 999999999;
    
    struct Node {
        int v;
        int c;
        Node(){}
        Node(int V, int C) {
            v = V;
            c = C;
        }
    };
    
    int n;
    std::vector<Node > v[10010];
    int Fmax[10010];//first maxn
    int Smax[10010];//second maxn
    int visf[10010];//标记最大距离来自的电脑标号 int viss[10010];//标记次大距离来自的电脑标号 void init(int n) { for (int i=0; i<=n; i++) { v[i].clear(); } for (int i=0; i<=n; i++) { Fmax[i] = Smax[i] = -INF; } } void dfs0(int t, int fa) { Fmax[t] = 0; Smax[t] = 0; for (int i=0; i<v[t].size(); i++) { Node& kid = v[t][i]; if (kid.v == fa) continue;//cout << t << " " << kid.v <<endl; dfs0(kid.v, t); if (Fmax[t] < Fmax[kid.v] + kid.c) { Smax[t] = Fmax[t]; Fmax[t] = Fmax[kid.v] + kid.c; viss[t] = visf[t]; visf[t] = kid.v; } else if (Smax[t] < Fmax[kid.v] + kid.c) { Smax[t] = Fmax[kid.v] + kid.c; viss[t] = kid.v; } } } void dfs1(int t, int fa, int l) { if (t != 1) { if (visf[fa] == t) { if (Fmax[t] < Smax[fa] + l) { Smax[t] = Fmax[t]; viss[t] = visf[t]; Fmax[t] = Smax[fa] + l; visf[t] = fa; } else if (Smax[t] < Smax[fa] + l) { Smax[t] = Smax[fa] + l; viss[t] = fa; } } else { if (Fmax[t] < Fmax[fa] + l) { Smax[t] = Fmax[t]; viss[t] = visf[t]; Fmax[t] = Fmax[fa] + l; visf[t] = fa; } else if (Smax[t] < Fmax[fa] + l) { Smax[t] = Fmax[fa] + l; viss[t] = fa; } } } for (int i=0; i<v[t].size(); i++) { if (v[t][i].v == fa) continue; dfs1(v[t][i].v, t, v[t][i].c); } } int main () { while (cin >> n) { init(n ); int a, b; for (int i=2; i<=n; i++) { cin >> a >> b; v[i].push_back(Node(a,b)); v[a].push_back(Node(i,b)); } dfs0(1, -1); dfs1(1, -1, 0); for (int i=1; i<=n; i++) { cout << Fmax[i] <<endl; } } return 0; }


    <!--眼看寒假接近尾声,自己却一事无成,浑浑噩噩度过一个月,拿什么再去见人。最终败给自己的还是惰性。-->

     
  • 相关阅读:
    [bzoj1568]李超线段树模板题(标志永久化)
    [tyvj1860]后缀数组
    [poj3264]rmq算法学习(ST表)
    LintCode-82.落单的数
    LintCode-53.翻转字符串
    LintCode-56.两数之和
    LintCode-379.将数组重新排序以构造最小值
    LintCode-5.第k大元素
    LintCode-3.统计数字
    LintCode-4.丑数 II
  • 原文地址:https://www.cnblogs.com/xuelanghu/p/4298861.html
Copyright © 2011-2022 走看看