zoukankan      html  css  js  c++  java
  • P3398 仓鼠找sugar lca

      

    题目描述

    小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n。地下洞穴是一个树形结构。这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c)到图书馆(d)。他们都会走最短路径。现在小仓鼠希望知道,有没有可能在某个地方,可以碰到他的基友?

    小仓鼠那么弱,还要天天被zzq大爷虐,请你快来救救他吧!

    输入输出格式

    输入格式:

    第一行两个正整数n和q,表示这棵树节点的个数和询问的个数。

    接下来n-1行,每行两个正整数u和v,表示节点u到节点v之间有一条边。

    接下来q行,每行四个正整数a、b、c和d,表示节点编号,也就是一次询问,其意义如上。

    输出格式:

    对于每个询问,如果有公共点,输出大写字母“Y”;否则输出“N”。

    输入输出样例

    输入样例#1: 复制
    5 5
    2 5
    4 2
    1 3
    1 4
    5 1 5 1
    2 2 1 4
    4 1 3 4
    3 1 1 5
    3 5 1 4
    输出样例#1: 复制
    Y
    N
    Y
    Y
    Y

    求树上路径是否相交
    询问树上ab,c到d的两条路径是否相交
    我们容易发现,如果相交,记 x=lca(a,b)y=lca(c,d),则必有x在c~d路径上或ya~b路径上
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=500000+5;
    const int M=2*500000+5;
    struct Edge
    {
        int nex,v,to;
    }edge[M];
    int lg[N],head[M],pos;
    void init(int n)//常数优化
    {
        pos=0;
        CLR(head,0);
        for(int i=1;i<=n;i++)
            lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    }
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].to=b;
    }
    int fa[N][100];
    int deth[N];
    void dfs(int cur,int fath)
    {
        deth[cur]=deth[fath]+1;
        fa[cur][0]=fath;
        for(int i=1;(1<<i)<=deth[cur];i++)
        fa[cur][i]=fa[ fa[cur][i-1] ][i-1];
    
        for(int i=head[cur];i;i=edge[i].nex)
        if(edge[i].to!=fath)
            dfs(edge[i].to,cur);
    }
    int lca(int x,int y)
    {
        if(deth[x]<deth[y])
        swap(x,y);
        while(deth[x]>deth[y])
        x=fa[x][ lg[ deth[x]-deth[y] ]-1];
        if(x==y)return x;
        for(int k=lg[deth[x]]-1;k>=0;k--)
        if(fa[x][k]!=fa[y][k])
        x=fa[x][k],y=fa[y][k];
        return fa[x][0];
    }
    int n,m,q,a,b,c,d;
    int dis(int a,int b)
    {
        int c=lca(a,b);
        return abs(deth[c]-deth[a])+abs(deth[c]-deth[b]);
    }
    int main()
    {
        RII(n,m);
        init(n);
        rep(i,1,n-1)
        {
            RII(a,b);add(a,b);add(b,a);
        }
        dfs(1,0);
        rep(i,1,m)
        {
            RII(a,b);RII(c,d);
            int x=lca(a,b),y=lca(c,d);
            if(dis(a,y)+dis(b,y)==dis(a,b)||dis(c,d)==dis(c,x)+dis(d,x))
                puts("Y");
            else puts("N");
        }
        return 0;
    }
    View Code



  • 相关阅读:
    《Java并发编程的艺术》 第9章 Java中的线程池
    《Java并发编程的艺术》第6/7/8章 Java并发容器与框架/13个原子操作/并发工具类
    java锁总结
    《Java并发编程的艺术》第5章 Java中的锁 ——学习笔记
    《Java并发编程的艺术》第4章 Java并发编程基础 ——学习笔记
    Java并发编程的艺术(一、二章) ——学习笔记
    redis缓存使用SpringDataRedis
    商城06——solr索引库搭建&solr搜索功能实现&图片显示问题解决
    商城05——首页轮播图显示实现&Redis环境搭建&Redis实现缓存
    商城04——门户网站介绍&商城首页搭建&内容系统创建&CMS实现
  • 原文地址:https://www.cnblogs.com/bxd123/p/11003416.html
Copyright © 2011-2022 走看看