樹上倍增求LCA
阿新 • • 發佈:2019-01-30
#include<set> #include<map> #include<cmath> #include<queue> #include<stack> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 500007 using namespace std; int N; int M; int S; int cnt; int f[MAXN]; int lv[MAXN]; int anc[MAXN][37]; int head[MAXN]; struct Edge { int to; int next; } edge[MAXN*2]; inline void add(int u,int v) { edge[++cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; return ; } inline int LCA(int x,int y) { if (lv[x]<lv[y]) swap(x,y); for (int i=22;i>=0;i--) { if (lv[y]<=lv[anc[x][i]]) x=anc[x][i]; } if (x==y) return x; for (int i=22;i>=0;i--) { if (anc[x][i]!=anc[y][i]) { x=anc[x][i]; y=anc[y][i]; } } return anc[x][0]; } inline void DFS(int u) { anc[u][0]=f[u]; for (int i=1;i<=22;i++) anc[u][i]=anc[anc[u][i-1]][i-1]; for (int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if (v!=f[u]) { f[v]=u; lv[v]=lv[u]+1; DFS(v); } } return ; } inline void solve() { scanf("%d%d%d",&N,&M,&S); for (int a,b,i=1;i<=N-1;i++) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } lv[S]=1; f[S]=S; DFS(S); for (int a,b,c,i=1;i<=M;i++) { scanf("%d%d",&a,&b); printf("%d\n",LCA(a,b)); } return ; } int main() { solve(); return 0; }// 由於小武比較懶,加上語言表達能力極低,在這裡只能為你們貼上一段倍增求LCA的十分美觀的程式碼了 歡迎已經瞭解LCA思想的人帶走我的程式碼 嘿嘿