zoukankan      html  css  js  c++  java
  • bzoj3124: [Sdoi2013]直径 树形dp two points

    题目链接

    bzoj3124: [Sdoi2013]直径

    题解

    发现所有直径都经过的边
    一定在一条直径上,并且是连续的
    在一条直径上找这段区间的两个就好了

    代码

    #include<map> 
    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
    #define gc getchar()
    #define pc putchar
    #define int long long 
    inline int read() { 
        int x = 0,f = 1; 
        char c = gc; 
        while(c < '0' || c > '9') { if(c == '-') f =- 1;c = gc;}  
        while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = gc; 
        return x * f; 
    } 
    void print(int x) { 
        if(x < 0) { 
            pc('-'); 
            x = -x; 
        } 
        if(x >= 10) print(x / 10); 
        pc(x % 10 + '0'); 
    } 
    int n; 
    const int maxn = 400007; 
    struct node { 
        int v,w,next;
    } edge[maxn << 1]; 
    int head[maxn],num = 0; 
    inline void add_edge(int u,int v,int w) { 
        edge[++ num].v = v; edge[num].w = w; edge[num].next = head[u]; head[u] = num; 
    } 
    int st,mx,dis[maxn],fa[maxn]; 
    void dfs(int x,int Fa) { 
        if(dis[x] > mx) { 
            mx = dis[x]; st = x; 
        } 
        fa[x] = Fa; 
        for(int i = head[x];i;i = edge[i].next) {
            int v = edge[i].v; 
            if(v == Fa) continue; 
            dis[v] = dis[x] + edge[i].w; 
            dfs(v,x); 
        } 
    } 
    int chain[maxn]; 
    int rdis[maxn],MX; 
    bool vis[maxn]; 
    void rdfs(int x,int Fa) { 
        vis[x] = true; 
        MX = std::max(MX,rdis[x]); 
        for(int i = head[x];i;i = edge[i].next) { 
            int v = edge[i].v; 
            if(vis[v] || v == Fa) continue; 
            rdis[v] = rdis[x] + edge[i].w; 
            rdfs(v,x); 
        } 
    } 
    main() { 
        //freopen("3.in","r",stdin);  
         n = read(); 
        for(int u,v,w,i = 1;i < n;++ i) { 
            u = read(),v = read(),w = read(); 
            add_edge(u,v,w); 
            add_edge(v,u,w); 
        } 
        dfs(1,0); 
        dis[st] = 0; 
        mx = 0; 
        dfs(st,0); 
        int len = 0; 
        while(st) { 
            chain[++ len] = st; 
            vis[st] = true; 
            st = fa[st]; 
        } 
        int l = len,r = 1; 
        for(int i = len;i >= 1;-- i) { 
            MX = 0; 
            rdfs(chain[i],0); 
            if(!MX) continue; 
            if(MX == dis[chain[i]]) l = i; 
            if(MX == mx - dis[chain[i]]) {r = i;break;} 
        }    
        print(mx); 
        pc('
    '); 
        print(l - r); 
    }   
    /* 
    6 
    3 1 1000
    1 4 10
    4 2 100
    4 5 50
    4 6 100
    */
    
    
  • 相关阅读:
    CentOS7怎样安装Nginx1.12.2
    CentOS7怎样安装MySQL5.7.22
    CentOS7怎样安装Java8
    CentOS安装JMeter
    CentOS安装nmon
    Unsupported major.minor version 51.0
    ssh问题_2
    数据库索引
    Name node is in safe mode.
    hadoop节点之间通信问题
  • 原文地址:https://www.cnblogs.com/sssy/p/9889292.html
Copyright © 2011-2022 走看看