• P3398 仓鼠找sugar


    仓鼠找sugar

    洛谷链接

    一道提高+/省选-的题目,终于可以提高博客题目的平均难度了。。。

    大致题意就是在一棵树上有两条路径,询问这两个路径是不是可以相交。

    而如果两条路径相交的话,一定有一条路径a两端点的LCA在另一条的路径上,我们可以通过求路径a的LCA是不是在路径b上来求出a与b是不是相交的。

    根据以上推断,可以保证了路径a的LCA的深度一定大于路径b的LCA的深度。只要再在确定路径a的LCA与路径b的两端点其中一点的LCA是路径a的LCA就确保路径a的LCA在路径b上了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #define N 100010
     4 #define M 200010
     5 using namespace std;
     6 int next[M],to[M],num,head[N],size[N],father[N],deep[N],top[N],n,m,a,b,c,d,lca_a_b,lca_c_d;
     7 void add(int false_from,int false_to){
     8     next[++num]=head[false_from];
     9     to[num]=false_to;
    10     head[false_from]=num;
    11 }
    12 void dfs1(int x){
    13     size[x]=1;
    14     deep[x]=deep[father[x]]+1;
    15     for(int i=head[x];i;i=next[i])
    16         if(father[x]!=to[i]){
    17             father[to[i]]=x;
    18             dfs1(to[i]);
    19             size[x]+=size[to[i]];
    20         }
    21 }
    22 void dfs2(int x){
    23     int mmax=0;
    24     if(!top[x])
    25         top[x]=x;
    26     for(int i=head[x];i;i=next[i])
    27         if(father[x]!=to[i]&&size[to[i]]>size[mmax])
    28             mmax=to[i];
    29     if(mmax){
    30         top[mmax]=top[x];
    31         dfs2(mmax);
    32     }
    33     for(int i=head[x];i;i=next[i])
    34         if(father[x]!=to[i]&&to[i]!=mmax)
    35             dfs2(to[i]);
    36 }
    37 int lca(int x,int y){
    38     while(top[x]!=top[y]){
    39         if(deep[top[x]]<deep[top[y]])
    40             swap(x,y);
    41         x=father[top[x]];
    42     }
    43     if(deep[x]<deep[y])return x;
    44     return y;
    45 }
    46 int main(){
    47     scanf("%d%d",&n,&m);
    48     for(int i=1;i<n;++i){
    49         scanf("%d%d",&a,&b);
    50         add(a,b);
    51         add(b,a);
    52     }
    53     dfs1(1);
    54     dfs2(1);
    55     for(int i=1;i<=m;++i){
    56         scanf("%d%d%d%d",&a,&b,&c,&d);
    57         lca_a_b=lca(a,b);
    58         lca_c_d=lca(c,d);
    59         if(deep[lca_a_b]==deep[lca_c_d]){
    60             if(lca_a_b==lca_c_d){
    61                 printf("Y
    ");
    62                 continue;
    63             }
    64             printf("N
    ");
    65             continue;
    66         }
    67         if(deep[lca_a_b]<deep[lca_c_d]){
    68             if(lca(lca_c_d,a)==lca_c_d||lca(lca_c_d,b)==lca_c_d)
    69                 printf("Y
    ");
    70             else
    71                 printf("N
    ");
    72         }
    73         if(deep[lca_a_b]>deep[lca_c_d]){
    74             if(lca(lca_a_b,c)==lca_a_b||lca(lca_a_b,d)==lca_a_b)
    75                 printf("Y
    ");
    76             else
    77                 printf("N
    ");
    78         }
    79     }
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    建设是为“有” 共享是为“无”
    设计模式-命令模式
    设计模式-建造者模式
    设计模式-抽象工厂模式(升级版工厂方法模式)
    设计模式-原型模式
    设计模式-单例模式
    Java中的多维数组
    设计模式-装饰者
    设计模式-模板方法
    乐观锁与悲观锁
  • 原文地址:https://www.cnblogs.com/jsawz/p/6817094.html
Copyright © 2020-2023  润新知