码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu P3398 仓鼠找sugar

时间:2019-07-21 14:57:36      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:||   相交   click   ret   target   block   判断   amp   name   

传送门

我居然把swap写成了switch

如果路径相交,那么一定有LCA(a,b)在路径c,d上,或LCA(c,d)在路径a,b上

如果x在路径a,b上,需要满足条件:

dpth[x] >= dpth[LCA(a,b)] 

LCA(a,x)=x 或 LCA(b,x)=x

就这样,求出LCA后分别判断一下即可

代码如下

技术图片
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;
const int maxn = 2e5+10;
int n,q,x,y,a,b,c,d,e,f,cnt;
int dpth[maxn],p[maxn][25];
int head[maxn],to[maxn],nxt[maxn];

void add(int x,int y) {
    to[++cnt] = y;
    nxt[cnt] = head[x];
    head[x] = cnt;
}

void dfs(int x,int fa) {
    dpth[x] = dpth[fa]+1;
    p[x][0] = fa;
    for(int i = 1; (1<<i) <= dpth[x]; i++)
        p[x][i] = p[p[x][i-1]][i-1];
    for(int i = head[x]; i; i = nxt[i]) {
        if(dpth[to[i]]) continue;
        if(to[i] == fa) continue;
        dfs(to[i],x);
    }
}

int lca(int a,int b) {
    if(dpth[a] < dpth[b]) swap(a,b);
    for(int i = 20; i >= 0; i--)
        if(dpth[a] - (1<<i) >= dpth[b])
            a = p[a][i];
    if(a == b) return a;
    for(int i = 20; i >= 0; i--)
        if(p[a][i] != p[b][i])
            a = p[a][i],b = p[b][i];
    return p[a][0];
}

bool check(int a,int b,int c,int d) {
    if(dpth[d] >= dpth[c])
        if(lca(a,d)==d || lca(b,d)==d)
            return true;
    return false;
}

int main() {
    scanf("%d%d",&n,&q);
    for(int i = 1; i <= n-1; i++) {
        scanf("%d%d",&x,&y);
        add(x,y),add(y,x);
    }
    dfs(1,-1);
    while(q--) {
        scanf("%d%d%d%d",&a,&b,&c,&d);
        e = lca(a,b);
        f = lca(c,d);
        if(check(a,b,e,f) || check(c,d,f,e))
            printf("Y\n");
        else printf("N\n");
    }
    return 0;
}
View Code

 

Luogu P3398 仓鼠找sugar

标签:||   相交   click   ret   target   block   判断   amp   name   

原文地址:https://www.cnblogs.com/mogeko/p/11221187.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!