标签:min swap nbsp int bsp iii sizeof oid dfs
首先dfs,记录每个点第一次被访问到的时间
那么区间LCA其实就是访问最早和访问最晚的点的LCA
找时间最早和最晚用ST表,找LCA用倍增
1 #include<stdio.h> 2 #include<string.h> 3 int n,tot,dfsclk,h[300010],nex[600010],to[600010],dfsnum[300010],dfsid[300010],dep[300010],fa[300010][20],stmin[300010][20],stmax[300010][20],log2[300010]; 4 void add(int a,int b){ 5 tot++; 6 nex[tot]=h[a]; 7 to[tot]=b; 8 h[a]=tot; 9 } 10 void dfs(int x,int f,int d){ 11 fa[x][0]=f; 12 dep[x]=d; 13 dfsclk++; 14 dfsnum[x]=dfsclk; 15 dfsid[dfsclk]=x; 16 for(int i=h[x];i;i=nex[i]){ 17 if(to[i]!=f)dfs(to[i],x,d+1); 18 } 19 } 20 int max(int a,int b){return a>b?a:b;} 21 int min(int a,int b){return a<b?a:b;} 22 void swap(int&a,int&b){ 23 int t=a; 24 a=b; 25 b=t; 26 } 27 int lca(int x,int y){ 28 if(dep[x]<dep[y])swap(x,y); 29 int i; 30 for(i=19;i>=0;i--){ 31 if(dep[fa[x][i]]>=dep[y])x=fa[x][i]; 32 } 33 if(x==y)return x; 34 for(i=19;i>=0;i--){ 35 if(fa[x][i]!=fa[y][i]){ 36 x=fa[x][i]; 37 y=fa[y][i]; 38 } 39 } 40 return fa[x][0]; 41 } 42 int querymax(int l,int r){ 43 int k=log2[r-l]; 44 return max(stmax[l][k],stmax[r-(1<<k)+1][k]); 45 } 46 int querymin(int l,int r){ 47 int k=log2[r-l]; 48 return min(stmin[l][k],stmin[r-(1<<k)+1][k]); 49 } 50 int main(){ 51 int q,i,j,a,b; 52 while(~scanf("%d",&n)){ 53 tot=0; 54 memset(h,0,sizeof(h)); 55 for(i=1;i<n;i++){ 56 scanf("%d%d",&a,&b); 57 add(a,b); 58 add(b,a); 59 } 60 dfsclk=0; 61 dfs(1,0,1); 62 63 log2[0]=0; 64 for(i=1;i<=n;i++){ 65 stmin[i][0]=stmax[i][0]=dfsnum[i]; 66 log2[i]=log2[i-1]; 67 if((1<<log2[i])<=(i>>1))log2[i]++; 68 } 69 for(j=1;j<20;j++){ 70 for(i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1]; 71 } 72 for(j=1;j<20;j++){ 73 for(i=1;i+(1<<(j-1))<=n;i++){ 74 stmax[i][j]=max(stmax[i][j-1],stmax[i+(1<<(j-1))][j-1]); 75 stmin[i][j]=min(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]); 76 } 77 } 78 scanf("%d",&q); 79 while(q--){ 80 scanf("%d%d",&a,&b); 81 printf("%d\n",lca(dfsid[querymin(a,b)],dfsid[querymax(a,b)])); 82 } 83 } 84 }
标签:min swap nbsp int bsp iii sizeof oid dfs
原文地址:http://www.cnblogs.com/jefflyy/p/7300786.html