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

    题目描述

    小仓鼠的和他的基((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
    

    说明

    本题时限1s,内存限制128M,因新评测机速度较为接近NOIP评测机速度,请注意常数问题带来的影响。

    (20\%)的数据 (n<=200,q<=200)

    (40\%)的数据 (n<=2000,q<=2000)

    (70\%)的数据 (n<=50000,q<=50000)

    (100\%)的数据 (n<=100000,q<=100000)

    思路:

    其实,多画几个图模拟一下,可以发现如下一个神奇的规律:

    如果两条路径相交,那么一定有一条路径的LCA在另一条路径上

    而判断一个节点(x),是否在路径(a)-(b)上需要满足如下几个条件

        - d[x]>=d[LCA(a,b)]
    
        - LCA(a,x)=x或LCA(b,x)=x;
    

    其中d数组代表深度。

    所以分两种情况讨论一下即可

    时间复杂度(O(n log n)),下面是树剖求(LCA)的代码,倍增照样可以做,就是慢了点。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 100007
    using namespace std;
    int num,head[maxn],n,d[maxn],son[maxn],top[maxn],siz[maxn];
    int cnt,id[maxn],fa[maxn],m;
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int v,nxt;
    }e[maxn<<1];
    inline void ct(int u, int v) {
      e[++num].v=v;
      e[num].nxt=head[u];
      head[u]=num;
    }
    void dfs1(int u) {
      siz[u]=1;
      for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v!=fa[u]) {
          d[v]=d[u]+1;
          fa[v]=u;
          dfs1(v);
          siz[u]+=siz[v];
          if(siz[v]>siz[son[u]]) son[u]=v;
        }
      }
    }
    void dfs2(int u, int t) {
      id[u]=++cnt;
      top[u]=t;
      if(son[u]) dfs2(son[u],t);
      for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
      }
    }
    inline int lca(int x, int y) {
      int fx=top[x],fy=top[y];
      while(fx!=fy) {
        if(d[fx]<d[fy]) swap(x,y),swap(fx,fy);
        x=fa[fx],fx=top[x];
      }
      return d[x]>d[y]?y:x;
    }
    int main() {
      n=qread(),m=qread();
      for(int i=1,u,v;i<n;++i) {
        u=qread(),v=qread();
        ct(u,v),ct(v,u);
      }
      dfs1(1);dfs2(1,1);
      for(int i=1,a,b,c,p;i<=m;++i) {
        a=qread(),b=qread(),c=qread(),p=qread();
        int zrj=lca(a,b),cyh=lca(c,p);
        if(d[zrj]<d[cyh]) swap(zrj,cyh),swap(a,c),swap(b,p);
        if(lca(zrj,c)==zrj||lca(zrj,p)==zrj) printf("Y
    ");
        else printf("N
    ");
      }
      return 0;
    }
    
  • 相关阅读:
    ARPPING
    Oracle RAC 连接
    Win7 DCOM 配置中我的电脑出现红色箭头并且无属性显示的解决方法
    Ping命令
    Linux & Oracle 安装目录说明
    TCP 四次握手
    wireshark使用
    jcaptcha组件小小改造解决Invalid ID, could not validate une
    JustSniffer
    java 自己定义异常,记录日志简单说明!留着以后真接复制
  • 原文地址:https://www.cnblogs.com/grcyh/p/10226349.html
Copyright © 2011-2022 走看看