zoukankan      html  css  js  c++  java
  • 森林 [树的直径]

    森林


    color{red}{正解部分}

    考虑在加节点时维护 直径 u,vu, v, 和距离 直径 最远的点 ss, 在询问时直接将 ss链 截到直径端点即可 .
    在加入一个节点 xx 时, 这个节点可能会替代 u,vu,v, 或者替代 ss,


    注意在计算 ss 离直径距离 时需要留心 ss 是否在 直径lca 下面, 计算方式不同 .


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 2e5 + 10;
    
    int N;
    int u;
    int v;
    int s;
    int Len;
    int dep[maxn];
    int Fk[maxn][20];
    
    int Lca(int x, int y){
            if(dep[x] < dep[y]) std::swap(x, y);
            for(reg int i = 19; i >= 0; i --) 
                    if(dep[Fk[x][i]] >= dep[y]) x = Fk[x][i];
            if(x == y) return x;
            for(reg int i = 19; i >= 0; i --)
                    if(Fk[x][i] != Fk[y][i]) x = Fk[x][i], y = Fk[y][i];
            return Fk[x][0];
    }
    
    int Dis(const int &x, const int &y){ return dep[x] + dep[y] - (dep[Lca(x, y)] << 1); }
    
    int Dis_2(int x){
            int lca = Lca(u, v);
            if(Lca(lca, x) == lca) return std::min(Dis(Lca(x, u), x), Dis(Lca(x, v), x));
            return Dis(lca, x);
    }
    
    void Add(int fa, int x){
            Fk[x][0] = fa; dep[x] = dep[fa] + 1;
            for(reg int i = 1; i <= 19; i ++) Fk[x][i] = Fk[Fk[x][i-1]][i-1];
            if(Dis(x, u) < Dis(x, v)) std::swap(u, v);
            int t = Dis(x, u);
            if(Len < t) Len = t, std::swap(x, v);
            if(Dis_2(x) > Dis_2(s)) s = x;
    }
    
    int main(){
            read(); N = read(); dep[1] = 1;
            u = v = s = 1;
            int last_ans = 0;
            for(reg int i = 2; i <= N; i ++){
                    int a = read() ^ last_ans;
                    Add(a, i);
                    printf("%d
    ", last_ans = Len + std::max(Dis_2(s)-1, 0));
            }
            return 0;
    }
    
  • 相关阅读:
    SpringBoot整合RabbitMQ
    RabbitMQ消息确认机制
    RabbitMQ六种队列模式-简单队列模式
    RabbitMQ六种队列模式-工作队列模式
    RabbitMQ六种队列模式-发布订阅模式
    RabbitMQ六种队列模式-路由模式
    RabbitMQ六种队列模式-主题模式
    RabbitMQ简单介绍+Windows环境安装
    SpringBoot整合ActiveMQ发送邮件
    下载缓慢文件记录,持续更新[2019-10-29]
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822463.html
Copyright © 2011-2022 走看看