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;
}edge[2*maxn];

int n,m,s,cnt,size[maxn],head[maxn],depth[maxn],son[maxn],fa[maxn],top[maxn];

void add(int u,int v){
    edge[++cnt].v=v;
    edge[cnt].next=head[u];
    head[u]=cnt;
}

void dfs1(int x){
    size[x]=1;
    depth[x]=depth[fa[x]]+1;
    for(int i=head[x];i;i=edge[i].next){
        int v=edge[i].v;
        if(v==fa[x]) continue;
        fa[v]=x;
        dfs1(v);
        size[x]+=size[v];
        if(!son[x]||size[son[x]]<size[v])
            son[x]=v;
    }
}

void dfs2(int x,int f){
    top[x]=f;
    if(son[x]) dfs2(son[x],f);
    for(int i=head[x];i;i=edge[i].next){
        int v=edge[i].v;
        if(v==fa[x]||v==son[x]) continue;
        dfs2(v,v);
    }
}

void lca(){
    for(int i=0;i<m;++i){
        int x,y;
        scanf("%d%d",&x,&y);
        while(top[x]!=top[y]){
            if(depth[top[x]]>depth[top[y]]) x=fa[top[x]];
            else y=fa[top[y]];
        }
        printf("%d\n",depth[x]<depth[y]?x:y);
    }
}

int main(){
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<n;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    dfs1(s);
    dfs2(s,s);
    lca();
    return 0;
}

原文地址:https://www.cnblogs.com/FrankChen831X/p/11167037.html

时间: 2024-08-02 11:42:25

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

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

树剖求LCA模板

O(logn)(n<=10^6) https://www.cnblogs.com/cangT-Tlan/p/8846408.html 把一棵树分成几条链,用数据结构去维护每一条链 1 #include<bits/stdc++.h> 2 #define ll long long 3 #define rll register ll 4 #define M 0x3f3f3f 5 #define For(i,l,r) for(int i=l;i<=r;i++) 6 using namesp

【树剖求LCA】树剖知识点

#include<cstdio> #include<iostream> using namespace std; struct edge{ int to,ne; }e[1000005]; int n,m,s,ecnt,head[500005],dep[500005],siz[500005],son[500005],top[500005],f[500005]; void add(int x,int y) //加边 { e[++ecnt].to=y; e[ecnt].ne=head[x

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

LCA[倍增][树剖][tarjan]

LCA:最近公共祖先 倍增: 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<vector> 5 using namespace std; 6 #define N 105 7 int deep[N],dad[N][21]; 8 vector<int>vec[N]; 9 int lca(int x,int y) { 10 if(deep[x]>dee