zoukankan      html  css  js  c++  java
  • hdu 2196 树形DP

    Computer

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


    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
     
    Author
    scnu
     
    Recommend
    lcy
     
    目测了众神中文算法后,自己code出来了。
    两次dfs:
    1.第一次,求出以当前节点u为树根的子树中离u的最大、次大权值及该路径中u的前一个节点; (后序遍历)
    2.第二次,因为在第一次中求出了当前点u在其子树中的两个不同路径最大权,那么以它出发的路径最大权为:

     max{子树路径最大权,父节点fa路径最大权(如果该路径前一节点 != u)/次大权(如果该路径前一节点 != u) + 当前边权}。(前序遍历)

     有向树即可,AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<map>
    
    using namespace std;
    
    #define LL long long
    #define ULL unsigned long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define cint const int
    #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    
    #define MAXN 11111
    #define MAXM 22222>>1
    
    struct edge{
        int u, v, w, nxt;
    }e[MAXM];
    int h[MAXN], cc, n;
    int fir_max[MAXN], sec_max[MAXN];
    int fir_id[MAXN], sec_id[MAXN];
    
    void add(int u, int v, int w){
        e[cc]=(edge){u, v, w, h[u]};
        h[u]=cc++;
    }
    
    void two_dis(int u){
        fir_max[u] = sec_max[u] = 0;
        for(int i=h[u]; i!=-1; i=e[i].nxt){
            int v=e[i].v, w=e[i].w;
            two_dis(v);                                 //搞完所有子节点再搞当前点
            if(fir_max[v]+w>=fir_max[u]){               //>=  考虑到边权为0的情况
                sec_max[u]=fir_max[u];      sec_id[u]=fir_id[u];
                fir_max[u]=fir_max[v]+w;    fir_id[u]=v;
            }
            else if(fir_max[v]+w>=sec_max[u]){
                sec_max[u]=fir_max[v]+w;
                sec_id[u]=v;
            }
        }
    }
    
    void max_dis(int u){
        for(int i=h[u]; i!=-1; i=e[i].nxt){
            int v=e[i].v, w=e[i].w;
            if(fir_id[u]!=v){                           //用从父节点出发的最大权更新
                int tw = w + fir_max[u];
                if(tw>=fir_max[v]){
                    sec_max[v] = fir_max[v];    sec_id[v] = fir_id[v];
                    fir_max[v] = tw;    fir_id[v] = u;
                }
                else if(tw>=sec_max[v]){
                    sec_max[v] = tw;    sec_id[v] = u;
                }
            }
    
            if(sec_id[u]!=v){                           //次大权更新
                int tw = w + sec_max[u];
                if(tw>=fir_max[v]){
                    sec_max[v] = fir_max[v];    sec_id[v] = fir_id[v];
                    fir_max[v] = tw;            fir_id[v] = u;
                }
                else if(tw>=sec_max[v]){
                    sec_max[v] = tw;    sec_id[v] = u;
                }
            }
            max_dis(v);                                 //去搞所有子节点
        }
    }
    
    int main(){
    //    freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        while(scanf(" %d", &n)==1){
            int u, v, w;
    
            memset(h, -1, sizeof(h));       cc=0;
            for(v=2; v<=n; v++){
                scanf(" %d %d", &u, &w);
                add(u, v, w);
            }
            two_dis(1);
            max_dis(1);
            for(u=1; u<=n; u++)
                printf("%d
    ", fir_max[u]);
        }
        return 0;
    }
    
  • 相关阅读:
    docker中 启动所有的容器命令
    使用Docker部署服务
    docker常规操作——启动、停止、重启容器实例
    Docker Swarm 常用命令
    ArcGIS中search窗口不能查询解决办法
    ylpy
    第7章
    ArcGIS 将模型导出为 Python 脚本
    11章代码
    9章代码
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3358281.html
Copyright © 2011-2022 走看看