写的略微复杂了一些,分了很多种类。
首先肯定只能写一次建树之后进行分类讨论查看位置
#include<iostream> #include<queue> #include<map> #include<vector> #include<cstdio> #include<algorithm> #include<stack> #include<cstring> 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]; int sz[N]; int dfn[N]; int times; 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 dfs(int u,int fa){ dfn[u]=++times; sz[u]=1; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs(j,u); sz[u]+=sz[j]; } return sz[u]; } int main(){ int n; while(cin>>n){ 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(); int m; cin>>m; dfs(1,-1); while(m--){ int root,x,y; scanf("%d%d%d",&root,&x,&y); if(dfn[x]>dfn[y]) swap(x,y); int p=lca(x,y); int ans=p; if(root==1) ans=p; else if(lca(root,p)==root){ ans=p; } else if(lca(root,x)==p&&lca(root,y)==p){ ans=p; } else{ if(lca(x,y)==x){ if(lca(root,x)==root) ans=x; else if(lca(root,x)==x&&lca(root,y)==root){ ans=root; } else if(lca(root,x)==x&&lca(root,y)!=root){ ans=lca(root,y); } else if(lca(root,x)==x&&lca(root,y)==y) ans=y; } else{ if(lca(root,x)==root&&lca(root,y)==p) ans=root; else if(lca(root,x)==p&&lca(root,y)==root) ans=root; else if(lca(root,x)==x) ans=x; else if(lca(root,y)==y) ans=y; else if(lca(root,x)==p&&lca(root,y)!=root) ans=lca(root,y); else if(lca(root,x)!=root&&lca(root,y)==p) ans=lca(root,x); } } cout<<ans<<endl; } } }