• [JZOJ 5852] [NOIP2018提高组模拟9.6] 相交 解题报告 (倍增+LCA)


    题目链接:

    http://172.16.0.132/senior/#main/show/5852

    题目:

    题目大意:

    多组询问,每次询问树上两条链是否相交

    题解:

    两条链相交并且仅当某一条链的两个端点的LCA在另一个端点上

    对于每次询问,我们分别处理出两条链端点的LCA,通过倍增判断是否存在一条链的LCA在另一条链上

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    const int N=1e5+15;
    int n,tot;
    int h[N],fa[N][20],dep[N];
    struct E{
        int to,nxt;
    }e[N<<1];
    inline int read(){
        char ch=getchar();int s=0,f=1;
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
        return s*f;
    }
    void link(int u,int v){e[++tot]=(E){v,h[u]};h[u]=tot;}
    void dfs(int x,int pre){
        for (int i=1;i<20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
        for (int i=h[x],y;i;i=e[i].nxt){
            if ((y=e[i].to)==pre) continue;
            fa[y][0]=x;dep[y]=dep[x]+1;
            dfs(y,x);
        }
    }
    int lca(int x,int y){
        if (dep[x]<dep[y]) swap(x,y);
        for (int i=19;i>=0;i--) if (dep[fa[x][i]]>=dep[y]) x=fa[x][i];
        if (x==y) return x;
        for (int i=19;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    bool chk(int a,int b,int La,int Lb){
        if (dep[Lb]<dep[La]) return 0;
        if (dep[a]>=dep[Lb]){
            for (int i=19;i>=0;i--) if (dep[fa[a][i]]>=dep[Lb]&&dep[fa[a][i]]>=dep[La]) a=fa[a][i];
            if (a==Lb) return 1;
        }
        if (dep[b]>=dep[Lb]){
            for (int i=19;i>=0;i--) if (dep[fa[b][i]]>=dep[Lb]&&dep[fa[b][i]]>=dep[La]) b=fa[b][i];
            if (b==Lb) return 1;
        }
        return 0;
    }
    int main(){
        freopen("inter.in","r",stdin);
        freopen("inter.out","w",stdout);
        n=read();
        for (int i=1,u,v;i<n;i++){
            u=read();v=read();
            link(u,v);link(v,u);
        }
        dep[1]=1;dfs(1,0);
        int q=read();
        while (q--){
            int a=read(),b=read(),c=read(),d=read();
            int lab=lca(a,b),lcd=lca(c,d);
            //printf("%d %d
    ",lab,lcd);
            if (chk(a,b,lab,lcd)||chk(c,d,lcd,lab)) puts("YES");
            else puts("NO");
        }
        return 0;
    }
  • 相关阅读:
    计算机组成原理实验总结
    Matlab图像匹配问题
    局域网实验
    信号量与共享存储区(操作系统实验三)
    路由器配置及IP设置及ping命令使用
    自我介绍是一门学问
    数据库管理系统的维护与管理
    高数讲课教后感
    node Unexpected token import(node 目前默认不支持es6 的模块 import解决方法有2)
    Cookie/Session机制详解
  • 原文地址:https://www.cnblogs.com/xxzh/p/9807105.html
Copyright © 2020-2023  润新知