• 洛谷P3398 仓鼠找sugar-LCA倍增/树剖


    题意

    一颗多叉树,给四个点,求有无公共点。

    基本思路

    倍增LCA,若$dep(lca(a,b))>dep(lca(cd))$,若有公共点,则$lca(lca(a,b),c)==lca(a,b)$或$lca(lca(a,b),d)==lca(a,b)$,反之亦然

    倍增做法

      1 #include<bits/stdc++.h>
      2 #define FOR(i,a,b) for(int i=a;i<b;i++)
      3 #define FOR2(i,a,b) for(int i=a;i<=b;i++)
      4 #define ll long long
      5 #define INF  0x7f7f7f7f;
      6 #define MAXN 200010
      7 #define MOD 10007
      8 #define MAXJUMP 22 
      9 using namespace std;
     10 typedef struct{
     11     int from,to,next;
     12 }EDGE;EDGE edges[MAXN]; 
     13 int a,b,c,d,n,m,s,ed=0,head[MAXN]; 
     14 int jump[MAXN][30],dep[MAXN];
     15 inline int read()
     16 {
     17     char ch=getchar();
     18     int x=0,f=1;
     19     while((ch>'9'||ch<'0')&&ch!='-')
     20         ch=getchar();
     21     if(ch=='-')
     22     {
     23         f=-1;
     24         ch=getchar();
     25     }
     26     while('0'<=ch&&ch<='9')
     27     {
     28         x=x*10+ch-'0';
     29         ch=getchar();
     30     }
     31     return x*f;
     32 }
     33 inline void put(int x)
     34 {
     35     if(x==0)
     36     {
     37         putchar('0');
     38         putchar('
    ');
     39         return;
     40     }
     41     int num=0;
     42     char c[25];
     43     while(x)
     44     {
     45         c[++num]=(x%10)+48;
     46         x/=10;
     47     }
     48     while(num)
     49         putchar(c[num--]);
     50     putchar('
    ');
     51     return ;
     52 }
     53 inline int log2(int x)
     54 {
     55     int k=0;while(x>1)x=x>>1,k++;return k;
     56 }
     57 inline void add(int a,int b)
     58 {
     59     edges[++ed].from=a;
     60     edges[ed].to=b;
     61     edges[ed].next=head[a];
     62     head[a]=ed;
     63     return;
     64 } 
     65 
     66 void dfs(int cur,int pre)
     67 {
     68     jump[cur][0]=pre;
     69     dep[cur]=dep[pre]+1;
     70     for(int i=1;i<=MAXJUMP;i++)
     71     {//记录跳点 
     72         jump[cur][i]=jump[jump[cur][i-1]][i-1];
     73     }
     74     for(int i=head[cur];i;i=edges[i].next)
     75     {
     76         if(edges[i].to==pre)continue;
     77         dfs(edges[i].to,cur);
     78     } 
     79 }
     80 int lca(int a,int b)
     81 {
     82     if(dep[a]<dep[b])
     83     {
     84         swap(a,b);
     85     }
     86     for(int i=MAXJUMP;i>=0;i--)
     87     {
     88         if((1<<i)<=dep[a]-dep[b])
     89         {
     90             a=jump[a][i];
     91         }
     92     }
     93     if(a==b)
     94         return a;
     95     for(int i=MAXJUMP;i>=0;i--)
     96     {
     97         if(jump[a][i]!=jump[b][i])
     98             a=jump[a][i],b=jump[b][i];
     99     }
    100     return jump[a][0];//返回共同父节点     
    101 }
    102 vector<int>q;
    103 int main()
    104 {//倍增 
    105     n=read();m=read();
    106     FOR(i,1,n)
    107     {
    108         a=read();b=read();
    109         add(a,b);add(b,a);q.push_back(b);
    110     }
    111     sort(q.begin(),q.end());
    112     FOR(i,0,q.size())
    113     {
    114         if(i+1!=q[i])
    115         {//确定起点 
    116             s=i+1;break;
    117         }
    118     }
    119     
    120     dfs(s,0);
    121     FOR(i,0,m)
    122     {
    123         a=read();b=read();c=read();d=read();
    124         int ab=lca(a,b);//cout<<ab<<" ";
    125         int cd=lca(c,d);//cout<<cd<<" ";
    126         
    127         if(dep[ab]>dep[cd])
    128         {
    129             if(ab==lca(ab,c)||ab==lca(ab,d)) cout<<"Y"<<endl;
    130             else cout<<"N"<<endl;
    131         }
    132         else {
    133             if(cd==lca(cd,a)||cd==lca(cd,b)) cout<<"Y"<<endl;
    134             else cout<<"N"<<endl;
    135         }
    136         
    137     }
    138     return 0;
    139 }
    View Code

    树剖做法

  • 相关阅读:
    The Road to Ryu: Hi Ryu
    Python学习札记(三十五) 面向对象编程 Object Oriented Program 6
    Python学习札记(三十四) 面向对象编程 Object Oriented Program 5
    Python学习札记(三十三) 面向对象编程 Object Oriented Program 4
    Python学习札记(三十二) 面向对象编程 Object Oriented Program 3
    Coursera SDN M1.2.1 SDN History: Programmable Networks 2
    Python学习札记(三十一) 面向对象编程 Object Oriented Program 2
    Python学习札记(三十) 面向对象编程 Object Oriented Program 1
    Coursera SDN M1.2.1 SDN History: Programmable Networks 1
    Python学习札记(二十九) 模块2
  • 原文地址:https://www.cnblogs.com/tldr/p/11296868.html
Copyright © 2020-2023  润新知