• LCA最近公共祖先


    LCA

    模板

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 100;
    int head[maxn], to[maxn * 2], nxt[maxn * 2], d[maxn * 2], tot;
    int n, m;
    void add(int x, int y, int w){
        to[++tot] = y; nxt[tot] = head[x]; d[tot] = w; head[x] = tot;
    }
    int dp[maxn][20], dep[maxn], dis[maxn];
    void dfs(int u, int fa){
        dp[u][0] = fa; dep[u] = dep[fa] + 1;
        for (int i = head[u]; i; i = nxt[i]){
            int v = to[i];
            if (v == fa) continue;
            dis[v] = dis[u] + d[i];
            dfs(v, u);
        }
    }
    void init(){
        memset(dp, 0, sizeof(dp));
        dep[0] = dis[0] = 0;
        dfs(1, 0); 
        for (int j = 1; j < 20; j++) 
            for (int i = 1; i <= n; i++) 
                dp[i][j] = dp[dp[i][j - 1]][j - 1];
    }
    int qlca(int x, int y){
        if (dep[x] < dep[y]) swap(x, y);
        int tmp = dep[x] - dep[y];
        for (int i = 0; tmp; i++, tmp >>= 1)
            if (tmp & 1) x = dp[x][i];
        if (x == y) return x;
        for (int i = 19; i >= 0; i--){
            if (dp[x][i] != dp[y][i]){
                x = dp[x][i]; y = dp[y][i];
            }
        }
        return dp[x][0];
    }
    int dist(int x,int y) {
        int u = qlca(x, y);
        int ans =  dis[x] + dis[y] - 2*dis[u];
        return dis[x] + dis[y] - 2*dis[u];
    }
    

    例题

    [CF1304E]1-Trees and Queries

    https://codeforces.com/contest/1304/problem/E

    题意

    给一棵树,每次查询时在x和y之间加一条边,然后问在a和b之间是否存在一条可以重复走的路径且这条路径的长度为k

    思路

    如果不走x和y的那条连边,那么a到b之间的路径长度为a与b的最短路径+2i,因为重复走的边对答案的贡献一定是偶数长度,只有走了x到y的那条连边,贡献为1,可以改变路径的奇偶性,枚举两种情况即可

    代码 : https://xlorpaste.cn/nmnq8r

  • 相关阅读:
    php7 安装xhprof
    通过explain分析SQL
    将本地代码上传到github
    SVM支持向量机分类算法
    sklearn之reshape(-1,1)
    sklearn之决策树和随机森林对iris的处理比较
    sklearn总结
    面向对象之类的继承
    面向对象之静态方法、类方法
    面向对象之类的私有属性和方法
  • 原文地址:https://www.cnblogs.com/guaguastandup/p/12589531.html
Copyright © 2020-2023  润新知