牛客 Borrow Classroom (LCA)
简单lca问题,只需要求一下三个点的lca判断一下距离即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; int h[N],ne[N],e[N],idx; int n,q; int depth[N],fa[N][25]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void bfs(){ memset(depth,0x3f,sizeof depth); depth[0]=0,depth[1]=1; int i; queue<int> q; q.push(1); while(q.size()){ int t=q.front(); q.pop(); for(i=h[t];i!=-1;i=ne[i]){ int j=e[i]; if(depth[j]>depth[t]+1){ depth[j]=depth[t]+1; q.push(j); fa[j][0]=t; for(int k=1;k<=21;k++){ fa[j][k]=fa[fa[j][k-1]][k-1]; } } } } } int lca(int a,int b){ if(depth[a]<depth[b]) swap(a,b); int i; for(i=21;i>=0;i--){ if(depth[fa[a][i]]>=depth[b]){ a=fa[a][i]; } } if(a==b) return a; for(i=21;i>=0;i--){ if(fa[a][i]!=fa[b][i]){ a=fa[a][i]; b=fa[b][i]; } } return fa[a][0]; } int main(){ int t; cin>>t; while(t--){ idx=0; cin>>n>>q; int i; memset(h,-1,sizeof h); for(i=1;i<n;i++){ int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } bfs(); for(i=1;i<=q;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); int p1=lca(b,c); int ans1=depth[b]+depth[c]-2*depth[p1]; int p2=lca(c,a); if(ans1+depth[c]-depth[p2]>=depth[a]-depth[p2]){ if(ans1+depth[c]-depth[p2]==depth[a]-depth[p2]&&p2==1) cout<<"NO"<<endl; else cout<<"YES"<<endl; } else{ cout<<"NO"<<endl; } } } }
没有人不辛苦,只有人不喊疼