//LCA //Tarjan 离线 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #define maxn 500001 using namespace std; int n,m,root,cnt,lca[maxn],head[maxn],jdg[maxn],fa[maxn],set[maxn];//set并查集 int cntget,headget[maxn]; struct uio{ int to,next; }edge[2*maxn]; struct oiu{ int to,next,num;//num表示第几次询问 }get[2*maxn]; inline int read() { int k=0,f=1; char c=getchar(); for(; !isdigit(c);c = getchar()) if(c=='-') f = -1; for(; isdigit(c);c = getchar()) k=k*10+c-'0'; return k*f; } void add(int u,int v) { edge[++cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; } void addget(int u,int v,int w) { get[++cntget].to=v; get[cntget].next=headget[u]; headget[u]=cntget; get[cntget].num=w;//记录是第几次询问 } int find(int x) { if(x==set[x]) return x; return set[x]=find(set[x]); } void tarjan(int x) { jdg[x]=1; set[x]=x; for(int i=head[x];i!=-1;i=edge[i].next) if(!jdg[edge[i].to]) { tarjan(edge[i].to); set[edge[i].to]=x; } for(int i=headget[x];i!=-1;i=get[i].next) if(jdg[get[i].to]==1) lca[get[i].num]=find(get[i].to); } int main() { // n=read(); // m=read(); // root=read(); scanf("%d%d%d",&n,&m,&root); memset(head,-1,sizeof(head)); memset(headget,-1,sizeof(headget)); for(int i=1;i<=n-1;i++) { int u,v; // int u=read(); // int v=read(); scanf("%d%d",&u,&v); add(u,v); add(v,u); } for(int i=1;i<=m;i++) { int u,v; // int u=read(); // int v=read(); scanf("%d%d",&u,&v); addget(u,v,i); addget(v,u,i); } tarjan(root); for(int i=1;i<=m;i++) printf("%d\n",lca[i]); return 0; }
LCA Tarjan
猜你喜欢
转载自www.cnblogs.com/water-radish/p/9280511.html
今日推荐
周排行