LCA
最近公共祖先。
一篇较好的博客:http://blog.csdn.net/y990041769/article/details/40887469
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<math.h> #include<queue> #include<vector> using namespace std; #define M 500001 int n,m,s,head[M],nex[M+M],num[M+M],deep[M],p[M][99]; void build1(int x,int d) { for(int i=head[x];i;i=nex[i]) { int t=num[i]; if(!p[t][0]) { p[t][0]=x; deep[t]=d; build1(t,d+1); } } return ; } void build2() { for(int j=1;(1<<j)<=n;j++) for(int i=1;i<=n;i++) if(!p[i][j]) p[i][j]=p[p[i][j-1]][j-1]; return; } inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();} return x*f; } int LCA(int a,int b) { if(deep[a]<deep[b]) { int c=b; b=a; a=c; } int i; for( i=0;(1<<i)<=deep[a];i++) ; i--; for (int j=i;j>=0;j--) if(deep[a]-(1<<j)>=deep[b]) a=p[a][j]; if(a==b) return a; for(int j=i;j>=0;j--) { if(p[a][0]==p[b][0]) return p[a][0]; if(p[a][j]!=-1&&p[a][j]!=p[b][j]) { a=p[a][j]; b=p[b][j]; } } return p[a][0]; } int main() { int cnt=0; //scanf("%d%d%d",&n,&m,&s); n=read();m=read();s=read(); for(int i=1,x,y;i<n;i++) { //scanf("%d%d",&x,&y); x=read();y=read(); num[++cnt]=x;nex[cnt]=head[y];head[y]=cnt; num[++cnt]=y;nex[cnt]=head[x];head[x]=cnt; } p[s][0]=-1; build1(s,1); build2(); for(int i=1,a,b;i<=m;i++) { //scanf("%d%d",&a,&b); a=read();b=read(); printf("%d\n",LCA(a,b)); } return 0;