LCA 模板

#include <bits/stdc++.h>

using namespace std;

#define REP(i,n)                for(int i(0); i <  (n); ++i)
#define rep(i,a,b)              for(int i(a); i <= (b); ++i)
#define dec(i,a,b)              for(int i(a); i >= (b); --i)
#define for_edge(i,x)           for(int i = H[x]; i; i = X[i])

const int N     =    100000      +       10;
const int M     =    10000       +       10;
const int Q     =    1000        +       10;
const int A     =    30          +       1;

int T;
int n, m;
int x, y, z;

int E[N << 1], X[N << 1], H[N << 1];
int deep[N];
int f[N][A];
int et;

inline void addedge(int a, int b){
    E[++et] = b, X[et] = H[a], H[a] = et;
    E[++et] = a, X[et] = H[b], H[b] = et;
}

void dfs(int x, int fa, int dep){
    deep[x] = dep;
    if (fa){
        f[x][0] = fa;
        for (int i = 0; f[f[x][i]][i]; ++i)
            f[x][i + 1] = f[f[x][i]][i];
    }

    for_edge(i, x) if (E[i] != fa){
        dfs(E[i], x, dep + 1);
    }
}

int LCA(int a, int b){
    if (deep[a] < deep[b]) swap(a, b);
    for (int i = 0,  delta = deep[a] - deep[b]; delta; delta >>= 1, ++i)
        if (delta & 1) a = f[a][i];

    if (a == b) return a;
    dec(i, 19, 0) if (f[a][i] != f[b][i]){
        a = f[a][i];
        b = f[b][i];
    }

    return f[a][0];
}

int main(){

    scanf("%d", &T);
    while (T--){
        et = 0;
        memset(H, 0, sizeof H);
        scanf("%d%d", &n, &m);
        rep(i, 1, n - 1){
            scanf("%d%d", &x, &y);
            addedge(x, y);
        }
        rep(i, 1, m){
            scanf("%d%d%d", &x, &y, &z);
        }
        dfs(1, 0, 0);
        rep(i, 1, n){
            for (int j = 0; f[i][j]; ++j) printf("%d ", f[i][j]);
            putchar(10);
        }

        rep(i, 1, n) printf("%d ", deep[i]);  putchar(10);

        printf("%d\n", LCA(4, 6));
        printf("%d\n", LCA(2, 3));
        printf("%d\n", LCA(4, 5));
    }

    return 0;

}

来自cxhscst2,<( ̄︶ ̄)>

时间: 2024-08-24 14:11:38

LCA 模板的相关文章

HDU 5296 Annoying problem(LCA模板+树的dfs序心得)

Problem Description Coco has a tree, whose nodes are conveniently labeled by 1,2,-,n, which has n-1 edge,each edge has a weight. An existing set S is initially empty. Now there are two kinds of operation: 1 x: If the node x is not in the set S, add n

算法复习——LCA模板(POJ1330)

题目: Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancesto

hdu 2586 LCA模板题(离线算法)

http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B&quo

LCA模板整理

HDU2586 纯LCA模板 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define lowbit(x) x&(-x) #define rep(i,l,r) for(int i=l;i<=r;++i) #define per(i,r,l) for(int i=r;i>=l;--i) #define ls o<<1 #defin

LCA模板(数剖实现)

题目链接:https://www.luogu.org/problemnew/show/P3379 题意:LCA模板题. 思路:今天开始学树剖,先拿lca练练.树剖解lca,两次dfs复杂度均为O(n),每次查询为logn,因此总复杂度为:O(2*n+m*logn). 代码: #include<cstdio> #include<cstring> using namespace std; const int maxn=500005; struct node{ int v,next; }

POJ 1330(LCA模板)

链接:http://poj.org/problem?id=1330 题意:q次询问求两个点u,v的LCA 思路:LCA模板题,首先找一下树的根,然后dfs预处理求LCA(u,v) AC代码: 1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<set> 6 #include<string> 7 #incl

hdu 2586 How far away? (LCA模板)

题意: N个点,形成一棵树,边有长度. M个询问,每个询问(a,b),询问a和b的距离 思路: 模板题,看代码.DFS预处理算出每个结点离根结点的距离. 注意: qhead[maxn],而不是qhead[maxm]. 输出用%I64d,不要用%lld. C++ RE后 尝试用 G++交. 代码: struct node{ int to,w,next,lca; }; int const maxn = 40005; int const maxm = 205; int fa[maxn]; int he

hihoCoder_#1067_最近公共祖先&#183;二(LCA模板)

#1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣--或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中辈分最低的一个是谁.远在美国的他们利用了一些奇妙的技术获得了国内许多人的相关信息,并且搭建了一个小小的网站来应付来自四面八方的请求. 但正如我们所能想象到的--这样一个简单的算法并不能支撑住非常大的访问量,所以摆在小Hi和小Ho面前的无非两种选择: 其一是购买更为昂

HDU 2586 How far away ?(LCA模板 近期公共祖先啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house

POJ 1330 Nearest Common Ancestors(LCA模板)

给定一棵树求任意两个节点的公共祖先 tarjan离线求LCA思想是,先把所有的查询保存起来,然后dfs一遍树的时候在判断.如果当前节点是要求的两个节点当中的一个,那么再判断另外一个是否已经访问过,如果访问过的话,那么它的最近公共祖先就是当前节点祖先. 下面是tarjan离线模板: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn =