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 }
请各位大佬斧正(反正我不认识斧正是什么意思)

 

posted @ 2019-07-24 13:58  handsome_zyc  阅读(111)  评论(0编辑  收藏  举报