题意:
裸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;
}