最近公共祖先LCA
code:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #define maxn 500010 using namespace std; template<typename T> inline void read(T &x){ x=0;bool flag=0;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') flag=1; for(;isdigit(c);c=getchar()) x=x*10+(c^48); if(flag) x=-x; } int n,m,s,x,y,a,b; int k=0,lg[maxn],f[maxn][25],head[maxn],deep[maxn]; struct node{ int v; int to; }e[2*maxn]; void add(int u,int v){ k++; e[k].to=v; e[k].v=head[u]; head[u]=k; } void dfs(int u,int fa){ deep[u]=deep[fa]+1; f[u][0]=fa; for(int i=1;(1<<i)<=deep[u];i++) f[u][i]=f[f[u][i-1]][i-1]; for(int i=head[u];i!=-1;i=e[i].v){ int to=e[i].to; if(to!=fa) dfs(to,u); } } int lca(int x,int y){ if(deep[x]<deep[y]) swap(x,y); while(deep[x]>deep[y]) x=f[x][lg[deep[x]-deep[y]]-1]; if(x==y) return x; for(int i=lg[deep[x]]-1;i>=0;i--){ if(f[x][i]!=f[y][i]){ x=f[x][i]; y=f[y][i]; } } return f[x][0]; } int main(){ read(n),read(m),read(s); memset(head,-1,sizeof(head)); for(int i=1;i<=n-1;i++){ read(x),read(y); add(x,y); add(y,x); } for(int i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<lg[i-1]==i); dfs(s,0); for(int i=1;i<=m;i++){ read(a),read(b); cout<<lca(a,b)<<endl; } return 0; }
某膜你赛题:
code:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define maxn 200010 using namespace std; template<typename T> inline void read(T &x){ x=0; bool flag=0; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') flag=1; for(;isdigit(c);c=getchar()) x=x*10+(c^48); if(flag) x=-x; } int n,t,x,y,a,b,c,d; int root,k=0,fa[maxn],head[maxn],deep[maxn],p[maxn][21]; struct node{ int v,next; }e[maxn*2]; void add(int u,int v){ e[k].v=v; e[k].next=head[u]; head[u]=k++; } void dfs(int u,int fa){ deep[u]=deep[fa]+1; p[u][0]=fa; for(int i=1;(1<<i)<=deep[u];i++) p[u][i]=p[p[u][i-1]][i-1]; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(v!=fa) dfs(v,u); } } int lca(int a,int b){ if(deep[a]>deep[b]) swap(a,b); for(int i=20;i>=0;i--) if(deep[a]<=deep[b]-(1<<i)) b=p[b][i]; if(a==b) return a; for(int i=20;i>=0;i--){ if(p[a][i]!=p[b][i]) a=p[a][i],b=p[b][i]; } return p[a][0]; } int dis(int a,int b){//注意求的是这个点在不在树的这一段上,所以不能直接比较LCA啊QAQ int c=lca(a,b); return abs(deep[c]-deep[a])+abs(deep[c]-deep[b]); } int main(){ // freopen("assassin.in","r",stdin); // freopen("assassin.out","w",stdout); read(n),read(t); memset(head,-1,sizeof(head)); for(int i=1;i<=n-1;i++){ read(x),read(y); fa[y]=x; add(x,y); add(y,x); } for(int i=1;i<=n;i++){ if(fa[i]==0){ root=i; break; } } // cout<<root<<endl; dfs(root,0); for(int i=1;i<=t;i++){ read(a),read(b),read(c),read(d); // read(a),read(b); int ans1=lca(a,b); int ans2=lca(c,d); // cout<<"***"<<ans1<<" "<<ans2<<"***"<<endl; if(dis(a,ans2)+dis(b,ans2)==dis(a,b)||dis(c,ans1)+dis(d,ans1)==dis(c,d)) cout<<"YES"<<endl;//******** else cout<<"NO"<<endl; } return 0; } /* 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 */ /* YES NO YES YES YES */