#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#define MAXN 100050
using namespace std;
map<string,int>id; //保存名字的标号
vector<int>edge[MAXN]; //邻接表
vector<int>query[MAXN]; //保存含某个名字的所有问题的标号
string name[MAXN]; //保存名字
string q1[MAXN],q2[MAXN]; //保存每个问题的左右两个名字
int ans[MAXN];
int fa[MAXN];
int name_s=1;
int get_id(string str)
{
if(!id[str])
{
id[str]=name_s;
name[name_s++]=str;
}
return id[str];
}
int Find(int x)
{
return x==fa[x]?x:fa[x]=Find(fa[x]);
}
void dfs(int loc,int pre) //前序遍历
{
fa[loc]=loc;
for(int i=0;i<edge[loc].size();i++)
dfs(edge[loc][i],loc);
for(int i=0;i<query[loc].size();i++) //含这个节点(名字)的所有问题
{
int j=query[loc][i];
int tmp=loc==id[q1[j]]? id[q2[j]] : id[q1[j]]; //找当前问题的另一个名字
if(fa[tmp]==-1) //另一个名字没访问过
continue;
ans[j]=Find(tmp);
}
fa[loc]=Find(fa[pre]); //合并到当前节点的根节点
return;
}
int main()
{
int n;
string a,b;
int t1,t2;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>a>>b;
t1=get_id(a);
t2=get_id(b);
edge[t1].push_back(t2);
}
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>q1[i]>>q2[i];
query[id[ q1[i] ] ].push_back(i);
query[id[ q2[i] ] ].push_back(i);
}
memset(fa,-1,sizeof(fa));
fa[0]=0;
dfs(1,0);
for(int i=1;i<=n;i++)
cout<<name[ans[i]]<<endl;
return 0;
}
hihocoder 1067(最近公共祖先tarjin)
最新推荐文章于 2024-03-21 20:01:16 发布