【luogu3398】 仓鼠找sugar [LCA 倍增]

P3398 仓鼠找sugar

长期不学竞赛...导致1mol的低级错误出现

  • 把f数组开为f[N][20]
  • 写错判断

我烂了QAQ我好瘟死于低级错误久久无法判断出来

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

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

    - deep[x]>=deep[LCA(s,t)]

    - LCA(s,x)=x或LCA(t,x)=x;
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int N=100000+5,inf=0x3f3f3f3f;
 5 int n,q,f[N][30],dep[N];
 6 bool vis[N];
 7 template<class t>void rd(t &x){
 8     x=0;int w=0;char ch=0;
 9     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
10     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
11     x=w?-x:x;
12 }
13 
14 int head[N],tot=0;
15 struct edge{int v,nxt;}e[N<<1];
16 void add(int u,int v){
17     e[++tot]=(edge){v,head[u]};head[u]=tot;
18 }
19 
20 void dfs(int u,int fa){
21     dep[u]=dep[fa]+1;
22     f[u][0]=fa;
23     for(int i=1;i<=20;++i){
24         if(dep[u]<(1<<i)) break;
25         f[u][i]=f[f[u][i-1]][i-1];
26     }
27     for(int i=head[u];i;i=e[i].nxt){
28         if(e[i].v==fa) continue;
29         dfs(e[i].v,u);
30     }
31 }
32 
33 int LCA(int a,int b){
34     if(dep[a]>dep[b]) swap(a,b);
35     for(int i=20;i>=0;--i){
36         if(dep[f[b][i]]<dep[a]) continue;
37         b=f[b][i];
38     }
39     if(b==a) return a;
40     for(int i=20;i>=0;--i){
41         if(f[a][i]==f[b][i]) continue;
42         a=f[a][i],b=f[b][i];
43     }
44     return f[a][0];
45 }
46 
47 
48 int main(){
49     freopen("in.txt","r",stdin);
50     memset(dep,0,sizeof(dep));
51     dep[0]=-1;
52     rd(n),rd(q);
53     for(int i=1,u,v;i<n;++i) rd(u),rd(v),add(u,v),add(v,u);
54     dfs(1,0);
55     for(int i=1,a,b,c,d,x,y;i<=q;++i){
56         rd(a),rd(b),rd(c),rd(d);
57         x=LCA(a,b),y=LCA(c,d);
58         if(dep[x]<dep[y]) swap(x,y),swap(a,c),swap(b,d);
59         if(LCA(x,c)==x||LCA(x,d)==x) printf("Y\n");
60         else printf("N\n");
61     }
62     return 0;
63 }

 

转载于:https://www.cnblogs.com/lxyyyy/p/11156365.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值