hihocoder 1067(最近公共祖先tarjin)

来源:互联网 发布:机械结构优化设计 编辑:程序博客网 时间:2024/05/30 04:53
#include<iostream>#include<cstdio>#include<cstring>#include<map>#include<vector>#define MAXN 100050using 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;}






原创粉丝点击