标签:span size swap rom namespace using void 运算 names
洛谷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 }
标签:span size swap rom namespace using void 运算 names
原文地址:http://www.cnblogs.com/Slager-Z/p/7771708.html