LOJ P10130 点的距离 题解
这道题相当于倍增求LCA的板子,我们只要构建一棵树,然后距离就是x的深度+y的深度 - LCA(x,y)的深度;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 100005 6 using namespace std; 7 int n,Q; 8 int x,y; 9 int next[maxn*2],first[maxn*2],go[maxn*2],tot; 10 int Dep[maxn]; 11 int f[maxn][21]; 12 inline int read() 13 { 14 int x=0; 15 bool f=1; 16 char c=getchar(); 17 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 18 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 19 if(f) return x; 20 return 0-x; 21 } 22 inline void add(int u,int v) 23 { 24 next[++tot]=first[u];first[u]=tot;go[tot]=v; 25 next[++tot]=first[v];first[v]=tot;go[tot]=u; 26 } 27 inline void Deal_first(int u,int father) 28 { 29 Dep[u]=Dep[father]+1; 30 for(int i=0;i<=19;i++) 31 { 32 f[u][i+1]=f[f[u][i]][i]; 33 } 34 for(int e=first[u];e;e=next[e]) 35 { 36 int v=go[e]; 37 if(v==father)continue; 38 f[v][0]=u; 39 Deal_first(v,u); 40 } 41 } 42 inline int LCA(int x,int y) 43 { 44 if(Dep[x]<Dep[y])swap(x,y); 45 for(int i=20;i>=0;i--) 46 { 47 if(Dep[f[x][i]]>=Dep[y])x=f[x][i]; 48 if(x==y)return x; 49 } 50 for(int i=20;i>=0;i--) 51 { 52 if(f[x][i]!=f[y][i]) 53 { 54 x=f[x][i]; 55 y=f[y][i]; 56 } 57 } 58 return f[x][0]; 59 } 60 inline int dist(int x,int y) 61 { 62 return Dep[x]+Dep[y]-2*Dep[LCA(x,y)]; 63 } 64 int main() 65 { 66 n=read(); 67 for(int i=1;i<n;i++) 68 { 69 x=read();y=read(); 70 add(x,y); 71 } 72 Deal_first(1,0); 73 Q=read(); 74 while(Q--) 75 { 76 x=read();y=read(); 77 printf("%d\n",dist(x,y)); 78 } 79 return 0; 80 }
请各位大佬斧正(反正我不认识斧正是什么意思)