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;
    }
    
    /*
    */
  • 相关阅读:
    CF1051F The Shortest Statement 题解
    CF819B Mister B and PR Shifts 题解
    HDU3686 Traffic Real Time Query System 题解
    HDU 5969 最大的位或 题解
    P3295 萌萌哒 题解
    BZOJ1854 连续攻击游戏 题解
    使用Python编写的对拍程序
    CF796C Bank Hacking 题解
    BZOJ2200 道路与航线 题解
    USACO07NOV Cow Relays G 题解
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10400213.html
Copyright © 2011-2022 走看看