#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <cstdlib> #include <queue> #include <stack> #include <vector> using namespace std; #define MAXN 100010 #define INF 10000009 #define MOD 10000007 #define LL long long #define in(a) a=read() #define REP(i,k,n) for(int i=k;i<=n;i++) #define DREP(i,k,n) for(int i=k;i>=n;i--) #define cl(a) memset(a,0,sizeof(a)) inline int read(){ int x=0,f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x; } inline void out(int x){ if(x<0) putchar('-'),x=-x; if(x>9) out(x/10); putchar(x%10+'0'); } int head[MAXN],to[MAXN],nxt[MAXN],f[MAXN],vis[MAXN]; int n,total=0,m; queue <int> Q; inline void adl(int a,int b){ total++; to[total]=b; nxt[total]=head[a]; head[a]=total; return ; } struct node{ int depth; int f[25]; }tree[MAXN]; inline void bfs(){ vis[1]=1; tree[1].depth=0; Q.push(1); while(!Q.empty()){ int u=Q.front(); Q.pop(); for(int e=head[u];e!=0;e=nxt[e]) if(!vis[to[e]]){ vis[to[e]]=1; tree[to[e]].f[0]=u; tree[to[e]].depth=tree[u].depth+1; Q.push(to[e]); } } return ; } inline void init(){ for(int i=1;(1<<i)<=n;i++) REP(j,1,n) tree[j].f[i]=tree[tree[j].f[i-1]].f[i-1]; } inline int lca(int u,int v){ if(tree[u].depth<tree[u].depth) swap(u,v); int d=tree[u].depth-tree[v].depth; for(int i=0;(1<<i)<=d;i++) if((1<<i) & d) u=tree[u].f[i]; if(u==v) return u; for(int i=20;i>=0;i--) if(tree[u].f[i]!=tree[v].f[i]){ u=tree[u].f[i]; v=tree[v].f[i]; } return tree[u].f[0]; } int main(){ in(n); REP(i,1,n-1){ int a,b; in(a);in(b); adl(a,b); adl(b,a); } bfs(); init(); REP(i,1,n){ REP(j,0,2) cout<<tree[i].f[j]<<" "; cout<<endl; } REP(i,1,n) printf("%d ",tree[i].depth); in(m); REP(j,1,m){ int a,b; in(a);in(b); printf("%d\n",lca(a,b)); } return 0; } /* 7 1 2 1 5 2 3 4 6 2 4 5 7 */
LCA算法模板
猜你喜欢
转载自www.cnblogs.com/jason2003/p/9443602.html
今日推荐
周排行