[模板]LCA
洛谷P3379
注意:不能与LCA搞混(打久了就会发现两个还是有很大区别的)
位运算一定要加括号!
for循环从0到logn还是从logn到0看当前的状态更适合哪种
第53行预处理一定要注意!(因为没有下标为-1的数组)
第34行也要注意如何判断当前是否跳点(不需要麻烦的位运算,因为如果能跳,dep[y]自然就会变,如果不跳,dep[y]又不变,每次与(dep[y]-dep[x])进行比较,不影响dep[x]与dep[y]的值;)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define man 500010 4 inline int read() 5 { int x=0;bool f=0; 6 char ch=getchar(); 7 while(ch<'0'||ch>'9'){f=(ch==45);ch=getchar();} 8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 9 return f?(~x+1):x; 10 } 11 int dep[man],f[man][30]; 12 int n,m,logn,root; 13 int head[man<<2],num=0; 14 struct edeg 15 { int next,to;}e[man<<2]; 16 inline void add(int from,int to) 17 { e[++num].next=head[from]; 18 e[num].to=to; 19 head[from]=num; 20 } 21 void dfs(int u,int fa,int depth) 22 { f[u][0]=fa; 23 dep[u]=depth; 24 for(int i=head[u];i;i=e[i].next) 25 { int to=e[i].to; 26 if(to==fa) continue; 27 dfs(to,u,depth+1); 28 } 29 return ; 30 } 31 inline int LCA(int x,int y) 32 { if(dep[x]>dep[y]) swap(x,y); 33 for(int i=0;i<logn;i++) 34 if(((dep[y]-dep[x])>>i)&1) y=f[y][i]; 35 if(x==y) return x; 36 for(int i=logn;i>=0;i--) 37 { if(f[x][i]!=f[y][i]) 38 { x=f[x][i];y=f[y][i]; 39 } 40 } 41 return f[x][0]; 42 } 43 int main() 44 { n=read(),m=read(),root=read(); 45 logn=(int)(log(n)/log(2.0))+1; 46 for(int i=1;i<n;i++) 47 { int u=read(),v=read(); 48 add(u,v);add(v,u); 49 } 50 dfs(root,-1,0); 51 for(int j=0;j<logn;j++) 52 for(int i=1;i<=n;i++) 53 if(f[i][j]<0) f[i][j+1]=-1; 54 else f[i][j+1]=f[f[i][j]][j]; 55 for(int i=1;i<=m;i++) 56 { int x=read(),y=read(); 57 printf("%d\n",LCA(x,y)); 58 } 59 return 0; 60 }
LCA使用BFS应该会快一点吧。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define man 500005 8 int n,m,root; 9 int head[man<<2],num=0; 10 inline int read() 11 { int x=0;bool f=0; 12 char ch=getchar(); 13 while(ch<'0'||ch>'9'){f=(ch==45);ch=getchar();} 14 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 15 return f?(~x+1):x; 16 } 17 struct edge 18 { int next,to;}e[man<<2]; 19 inline void add(int from,int to) 20 { e[++num].next=head[from]; 21 e[num].to=to; 22 head[from]=num; 23 } 24 int f[man][25],dep[man],logn; 25 bool vis[man]; 26 void bfs(int s,int dept) 27 { memset(vis,0,sizeof(vis)); 28 f[s][0]=-1;dep[s]=dept; 29 queue<int>q; 30 q.push(s); 31 do 32 { int u=q.front();q.pop();vis[u]=1; 33 for(int i=head[u];i;i=e[i].next) 34 { int to=e[i].to; 35 if(!vis[to]) 36 { f[to][0]=u; 37 dep[to]=dep[u]+1; 38 q.push(to);} 39 } 40 }while(q.size()); 41 } 42 inline int LCA(int x,int y) 43 { if(dep[x]>dep[y]) swap(x,y); 44 for(int i=0;i<logn;i++) 45 { if(((dep[y]-dep[x])>>i)&1) 46 y=f[y][i]; 47 } 48 if(x==y) return x; 49 for(int i=logn;i>=0;i--) 50 { if(f[x][i]!=f[y][i]) 51 { x=f[x][i]; 52 y=f[y][i]; 53 } 54 } 55 return f[x][0]; 56 } 57 int main() 58 { n=read(),m=read(),root=read(); 59 for(int i=1;i<n;i++) 60 { int x,y; 61 x=read(),y=read(); 62 add(x,y);add(y,x); 63 } 64 bfs(root,0); 65 logn=(int)(log(n)/log(2.0))+1; 66 for(int j=0;j<logn;j++) 67 for(int i=1;i<=n;i++) 68 if(f[i][j]<0) f[i][j+1]=-1; 69 else f[i][j+1]=f[f[i][j]][j]; 70 for(int i=1;i<=m;i++) 71 { int x,y; 72 x=read(),y=read(); 73 printf("%d\n",LCA(x,y)); 74 } 75 return 0; 76 }
欢迎大家吐槽或评论,如要转载请注明地址,谢谢~(虽然不一定有人能看到。。。)