zoukankan      html  css  js  c++  java
  • LCA模板

    树链剖分LCA
    O(n)-O(logn)

    #include<iostream>
    #include<cstdio>
    const int N=500005;
    int n,m,S,ecnt,head[N],tim;
    struct Edge{int to,nxt;}e[N<<1];
    void add(int bg,int ed){e[++ecnt].nxt=head[bg];e[ecnt].to=ed;head[bg]=ecnt;}
    int fa[N],dfn1[N],top[N],dfn2[N],son[N],dep[N],siz[N],rnk[N];
    void dfs1(int x){
        siz[x]=1;
        dep[x]=dep[fa[x]]+1;
        for(int i=head[x],v;i;i=e[i].nxt){v=e[i].to;
            if(v==fa[x]) continue;
            
            fa[v]=x;
            dfs1(v);
            siz[x]+=siz[v];
            if(siz[son[x]]<siz[v]) son[x]=v;
        }
    }
    void dfs2(int x,int qtop){
        top[x]=qtop;
        dfn1[x]=++tim;
        rnk[tim]=x;
        if(son[x]) dfs2(son[x],qtop);
        for(int i=head[x];i;i=e[i].nxt){
            int v=e[i].to;
            if(v==fa[x]||v==son[x])continue;
            dfs2(v,v);
        }
        dfn2[x]=tim;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&S);
        for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),add(u,v),add(v,u);
        dfs1(S);dfs2(S,S);
        for(int i=1,x,y;i<=m;i++){
            scanf("%d%d",&x,&y);
            while(top[x]!=top[y]){
                if(dep[top[x]]>=dep[top[y]]) x=fa[top[x]];
                else y=fa[top[y]];
            }
            printf("%d
    ",dep[x]<dep[y]?x:y);
        }
    }
    

    tarjan flag++;

    倍增 O(nlogn)-O(logn)

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=1000005;
    int n,q,nxt[N],to[N],fa[N][25],ecnt,head[N],dep[N],S;
    inline void add(int bg,int ed) {nxt[++ecnt]=head[bg];to[ecnt]=ed;head[bg]=ecnt;}
    void dfs(int x,int f) {
        fa[x][0]=f;dep[x]=dep[f]+1;
        for(int i=1;i<=24;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
        for(int i=head[x];i;i=nxt[i]) {
            if(to[i]==f) continue;
            dfs(to[i],x);
        }
    }
    int lca(int x,int y) {
        if(x==y) return x;
        if(dep[x]<dep[y])swap(x,y);
        for(int i=24;~i;i--) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
        //cout<<dep[x]<<' '<<dep[y]<<endl;
        if(x==y) return x;
        for(int i=24;~i;i--) 
            if(fa[x][i]!=fa[y][i]) 
            x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    int main() {
        scanf("%d%d%d",&n,&q,&S);
        for(int i=1,x,y;i<n;i++)  scanf("%d%d",&x,&y),add(x,y),add(y,x);
        dfs(S,0);
        int x,y;
        while(q--) {
            scanf("%d%d",&x,&y);
        	printf("%d
    ",lca(x,y));
        }
    } 
    

    RMQ+欧拉序 O(logn)-O(1)

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=1000005;
    int n,q,nxt[N],to[N],val[N],Min[25][N],ecnt,head[N],tim,dep[N],rnk[N],dfn[N],S,node[25][N];
    inline void add(int bg,int ed) {nxt[++ecnt]=head[bg];to[ecnt]=ed;head[bg]=ecnt;}
    void dfs(int x,int f) {
        dep[x]=dep[f]+1;dfn[x]=++tim;Min[0][tim]=dep[x];node[0][tim]=x;
        for(int i=head[x];i;i=nxt[i]) {
            if(to[i]==f) continue;
            dfs(to[i],x);
            Min[0][++tim]=dep[x];node[0][tim]=x;
        }
    }
    void ask(int x,int y) {
        if(x>y) swap(x,y);
        int k=log2(y-x+1);
        if(Min[k][x]<Min[k][y-(1<<k)+1]) printf("%d
    ",node[k][x]);
        else printf("%d
    ",node[k][y-(1<<k)+1]);
        return ;
    }
    int main() {
        scanf("%d%d%d",&n,&q,&S);
        for(int i=1,x,y;i<n;i++)  scanf("%d%d",&x,&y),add(x,y),add(y,x);
        dfs(S,0);
        for(int i=1;(1<<i)<=tim;i++) {
            for(int j=1;j+(1<<i)-1<=tim;j++) {
                if(Min[i-1][j]<Min[i-1][j+(1<<i-1)]) {
                    Min[i][j]=Min[i-1][j];
                    node[i][j]=node[i-1][j];
                }
                else {
                    Min[i][j]=Min[i-1][j+(1<<i-1)];
                    node[i][j]=node[i-1][j+(1<<i-1)];
                }
            }
        }
        int x,y;
        while(q--) {
            scanf("%d%d",&x,&y);
            ask(dfn[x],dfn[y]);
        }
    } 
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    POJ 2031 Building a Space Station 最小生成树模板
    POJ 2492 A Bug's Life 并查集
    HDU 2255 奔小康赚大钱 KM算法的简单解释
    HDU 2802 F(N) 数论+打表
    HDU 5455 Fang Fang 水题,但题意描述有问题
    LightOJ 1341 Aladdin and the Flying Carpet 算数基本定理
    LightOJ 1370 Bi-shoe and Phi-shoe 数论
    HDU 5652 India and China Origins 二分优化+BFS剪枝
    bzoj2287【POJ Challenge】消失之物(退背包)
    bzoj3297[USACO2011 Open]forgot(dp + string)
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9280879.html
Copyright © 2011-2022 走看看