【模板】倍增LCA

题号:洛谷3379

 1 %:pragma GCC optimize ("Ofast")
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cctype>
 5 inline int getint() {
 6     int ch;
 7     while(!isdigit(ch=getchar()));
 8     int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int N=500001,logN=19;
13 std::vector<int> e[N];
14 int anc[N][logN+1]={{0}},dep[N];
15 inline void add_edge(const int u,const int v) {
16     e[u].push_back(v);
17     e[v].push_back(u);
18 }
19 void dfs(const int x,const int parent,const int depth) {
20     anc[x][0]=parent,dep[x]=depth;
21     for(int i=1;i<=logN;i++) {
22         anc[x][i]=anc[anc[x][i-1]][i-1];
23     }
24     for(unsigned int i=0;i<e[x].size();i++) {
25         if(e[x][i]==parent) continue;
26         dfs(e[x][i],x,depth+1);
27     }
28 }
29 inline void swap(int &a,int &b) {
30     int t;
31     t=a;
32     a=b;
33     b=t;
34 }
35 int LCA(int a,int b) {
36     if(dep[a]<dep[b]) swap(a,b);
37     for(int i=logN;i>=0;i--) {
38         if(dep[a]-(1<<i)>=dep[b]) a=anc[a][i];
39     }
40     if(a==b) return a;
41     for(int i=logN;i>=0;i--) {
42         if(anc[a][i]&&anc[a][i]!=anc[b][i]) {
43             a=anc[a][i];
44             b=anc[b][i];
45         }
46     }
47     return anc[a][0];
48 }
49 int main() {
50     int n=getint(),m=getint(),s=getint();
51     for(int i=1;i<n;i++) add_edge(getint(),getint());
52     dfs(s,0,0);
53     while(m--) printf("%d\n",LCA(getint(),getint()));
54     return 0;
55 }

 

posted @ 2017-07-09 19:40  skylee03  阅读(170)  评论(0编辑  收藏  举报