zoukankan      html  css  js  c++  java
  • Codeforces 379F New Year Tree 树的直径的性质推理

    New Year Tree

    我们假设当前的直径两端为A, B, 那么现在加入v的两个儿子x, y。

    求直径的话我们可以第一次dfs找到最远点这个点必定为直径上的点, 然而用这个点第二次dfs找到最远点, 这两个点就是直径。

    因为A, B现在是直径的两端, 那么从v点dfs找到的最远点必定为A或者B, 那么从 x dfs找到的最远点也必定为A或者B, 那么如果有

    新的直径其中一个端点不会变, 当前图和原图的差别就是x和y, 那么比较dist(A, x), dist(B, x)和未加入前直径的长度就能得到当前的直径。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    using namespace std;
    
    const int N = 1e6 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int f[N][20], depth[N];
    int q;
    
    int getLca(int u, int v) {
        if(depth[u] < depth[v]) swap(u, v);
        for(int i = 19; i >= 0; i--)
            if(depth[f[u][i]] >= depth[v])
                u = f[u][i];
        if(u == v) return u;
        for(int i = 19; i >= 0; i--)
            if(f[u][i] != f[v][i])
                u = f[u][i], v = f[v][i];
        return f[u][0];
    }
    
    int dist(int u, int v) {
        int lca = getLca(u, v);
        return depth[u] + depth[v] - 2 * depth[lca];
    }
    
    int main() {
        depth[1] = 1;
        depth[2] = depth[3] = depth[4] = 2;
        f[2][0] = f[3][0] = f[4][0] = 1;
        int A = 2, B = 3, dia = 2, n = 4;
        scanf("%d", &q);
        while(q--) {
            int v; scanf("%d", &v);
            depth[n + 1] = depth[v] + 1;
            depth[n + 2] = depth[v] + 1;
            f[n + 1][0] = f[n + 2][0] = v;
            for(int i = 1; i < 20; i++) {
                f[n + 1][i] = f[f[n + 1][i - 1]][i - 1];
                f[n + 2][i] = f[f[n + 2][i - 1]][i - 1];
            }
            int d1 = dist(A, n + 1);
            int d2 = dist(B, n + 1);
            if(d1 > dia) dia = d1, B = n + 1;
            else if(d2 > dia) dia = d2, A = n + 1;
            printf("%d
    ", dia);
            n += 2;
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    Haskell Interactive Development in Emacs
    Access Java API in Groovy Script
    手工设置Eclipse文本编辑器的配色
    Color Theme of Emacs
    Gnucash的投资记录
    Special Forms and Syntax Sugars in Clojure
    Use w3m as Web Browser
    SSE指令集加速之 I420转BGR24
    【图像处理】 增加程序速度的方法
    TBB 入门笔记
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10400213.html
Copyright © 2011-2022 走看看