星星之火

[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\n",lab,lcd);
        if (chk(a,b,lab,lcd)||chk(c,d,lcd,lab)) puts("YES");
        else puts("NO");
    }
    return 0;
}
posted @ 2018-10-17 21:07  星星之火OIer  阅读(184)  评论(0编辑  收藏  举报