P3379 【模板】最近公共祖先(LCA)
LCA模板
询问离线 tarjan算法
#include<bits/stdc++.h> using namespace std; vector<int> v[500000+5]; int N,M,root; bool vis[500000+5]; struct Q { int x,y; int id; bool operator< (Q a) { if(a.x==x)return y<a.y; return x<a.x; } }; bool cmp(Q a,Q b) { if(a.x==b.x)return a.y<b.y; return a.x<b.x; } vector<Q>q; int fa[500000+5]; void init() { for(int i=1; i<=N; i++) { fa[i]=i; } } int find(int x) { return fa[x]=(x==fa[x]?x:find(fa[x])); } void merge(int x,int y) { int a=find(x); int b=find(y); fa[b]=a; } int ans[500000+5]; void tarjan(int r,int Fa) { //cout<<r<<' '; for(int i=0; i<v[r].size(); i++) { if(v[r][i]!=Fa) { tarjan(v[r][i],r); merge(r,v[r][i]); vis[v[r][i]]=1; } //fa[find(v[r][i])]=r; } Q t; t.x=r; t.y=t.id=0; int i=lower_bound(q.begin(),q.end(),t)-q.begin(); //cout<<r<<'r'<<endl; //cout<<i<<'i'<<' '; for(i; i<q.size(); i++) { //if(ans[i]==0) if(ans[q[i].id]==0) if((q[i].x==r&&vis[q[i].y])) { // cout<<q[i].id<<"www"<<endl; ans[q[i].id]=find(q[i].y); } if(q[i].x!=r)break; } } int main() { scanf("%d%d%d",&N,&M,&root); init(); int a,b; for(int i=0; i<N-1; i++) { scanf("%d%d",&a,&b); v[a].push_back(b); v[b].push_back(a); } for(int i=0; i<M; i++) { Q x,y; scanf("%d%d",&x.x,&x.y); x.id=i; y.x=x.y; y.y=x.x; y.id=i; q.push_back(x); q.push_back(y); } sort(q.begin(),q.end(),cmp); tarjan(root,-1); for(int i=0; i<M; i++) { cout<<ans[i]<<' '; } /*for(int i=1;i<=N;i++){ cout<<fa[i]<<' '; }*/ }