题意:
裸LCA
题解:
RMQ解LCA,其中F[]代表每个点第一次进入dfs的位置,D[]为搜索中的高度,E[]为每个搜索标记对应的点标号
Program:
#include<iostream> #include<stdio.h> #include<cmath> #include<map> #include<string> #include<string.h> #include<algorithm> #define MAXN 100005 #define oo 1000000007 #define ll long long using namespace std; struct Edge { int v,next; }edge[MAXN<<1]; map<string,int> H; string s,name[MAXN]; char st[1005]; int _next[MAXN],En,Vn,T[MAXN<<2]; int F[MAXN],E[MAXN],D[MAXN],DfsIndex; int Input() { scanf("%s",st),s=st; if (H.find(s)==H.end()) H[s]=++Vn,name[Vn]=s; return H[s]; } void addedge(int u,int v) { edge[++En].next=_next[u],_next[u]=En; edge[En].v=v; } void dfs(int u,int d) { D[++DfsIndex]=d,E[DfsIndex]=u; F[u]=DfsIndex; for (int k=_next[u];k;k=edge[k].next) { dfs(edge[k].v,d+1); D[++DfsIndex]=d,E[DfsIndex]=u; } } void Update(int l,int r,int L,int R,int d,int x) { if (l>=L && r<=R) { T[x]=d; return; } int mid=l+r>>1; if (mid>=L) Update(l,mid,L,R,d,x<<1); if (mid<R) Update(mid+1,r,L,R,d,x<<1|1); if (D[T[x<<1]]<D[T[x<<1|1]]) T[x]=T[x<<1]; else T[x]=T[x<<1|1]; return; } int Query(int l,int r,int L,int R,int x) { if (l>=L && r<=R) return T[x]; int mid=l+r>>1,temp,d=0; if (mid>=L) { temp=Query(l,mid,L,R,x<<1); if (!d || D[temp]<D[d]) d=temp; } if (mid<R) { temp=Query(mid+1,r,L,R,x<<1|1); if (!d || D[temp]<D[d]) d=temp; } return d; } void built_st(int n) { for (int i=1;i<=n;i++) Update(1,n,i,i,i,1); } int main() { int N,u,v,Q; scanf("%d",&N),Vn=0; memset(_next,0,sizeof(_next)),En=0; while (N--) { u=Input(),v=Input(); addedge(u,v); } DfsIndex=0; dfs(1,0); scanf("%d",&Q); built_st(DfsIndex); while (Q--) { u=Input(),v=Input(); puts(name[E[Query(1,DfsIndex,min(F[u],F[v]),max(F[u],F[v]),1)]].c_str()); } return 0; }