zoukankan      html  css  js  c++  java
  • 仓鼠找sugar(LCA)

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

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

    Solution

    这题数据不是很强,可以用两个log水过(考场上就这么写的)。但还有更优秀的一个log的做法。

    我们对于两对点,分别求出它们的LCA。

    如果两组LCA是同一个点,那么路径肯定有交。

    如果其中一个LCA比其它两个点还要深,那么路径肯定没有交。

    两种极端情况考虑完了。

    这时如果路径有交那么,其中一个lca一定是另外一组点中其中一个点的祖先。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define N 200009
    using namespace std;
    int p[N][25],head[N],deep[N],a,b,c,d,tot,n,q;
    struct ssd
    {
        int n,to;
    }an[N<<1];
    inline void add(int u,int v)
    {
        an[++tot].n=head[u];
        an[tot].to=v;
        head[u]=tot;
    }
    void dfs(int u,int fa)
    {
        deep[u]=deep[fa]+1;
        p[u][0]=fa;
        for(int i=1;(1<<i)<=deep[u];++i)
          p[u][i]=p[p[u][i-1]][i-1];
        for(int i=head[u];i;i=an[i].n)
        {
            int v=an[i].to;
            if(v!=fa)dfs(v,u);
        }
    }
    int lca(int u,int v)
    {
        if(deep[u]<deep[v])swap(u,v);
        for(int i=23;i>=0;--i)
          if(deep[u]-(1<<i)>=deep[v])u=p[u][i];
         if(u==v)return u;
        for(int i=23;i>=0;--i)
          if(p[u][i]!=p[v][i])u=p[u][i],v=p[v][i];
         return p[u][0]; 
    }
    int main()
    {
        scanf("%d%d",&n,&q);
        for(int i=1;i<n;++i)
          scanf("%d%d",&a,&b),add(a,b),add(b,a);
        dfs(1,0);
        while(q--)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            int l1=lca(a,b),l2=lca(c,d);
            if(l1==l2)printf("Y
    ");
            else if(deep[l1]>max(deep[c],deep[d])||deep[l2]>max(deep[a],deep[b]))printf("N
    ");
            else 
            {
                if(deep[l1]>deep[l2]){swap(l1,l2);swap(a,c);swap(b,d);}
                int l3=lca(l2,a),l4=lca(l2,b);
                if(l3==l2||l4==l2)printf("Y
    ");
                else printf("N
    ");
            }
       } 
        return 0;
    }
  • 相关阅读:
    浏览器允许跨域运行字符串
    检查失败,<master>分支有过其他更新,请先在本地合并<master>分支的代码
    微信公众号开发点点滴滴
    手机上的软件开发应该
    见过写过最好的代码
    Prometheus之新版node_exporter监控主机设置
    Granfana设置邮件告警
    linux 中添加自己的库路径的方法 cannot open shared object file: No such file or directory
    C# this.Invoke()的作用与用法
    C#中this.Invoke()中委托的定义
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9629871.html
Copyright © 2011-2022 走看看