1. 程式人生 > >最近公共祖先·三 HihoCoder

最近公共祖先·三 HihoCoder

  • #include<bits/stdc++.h>
    using namespace std;
    #define maxn 110000
    int n,k,q,sum;
    int deep[110001],tot;
    int head[110001],dp[110001][20];
    map<string,int>mmp;
    map<int,string>out;
    string str1,str2;
    struct node
    {
        int v,to;
    } edge[maxn*2];
    void add(int u,int v)
    {
        edge[++tot].v=v;
        edge[tot].to=head[u];
        head[u]=tot;
    }
    void dfs(int cur,int pre)
    {
        deep[cur]=deep[pre]+1;
        dp[cur][0]=pre;
        for(int i=1; (1<<i)<=deep[cur]; i++)
            dp[cur][i]=dp[dp[cur][i-1]][i-1];
        for(int i=head[cur]; i!=-1; i=edge[i].to)
            if(edge[i].v!=pre)
                dfs(edge[i].v,cur);
    }
    int lca(int x,int y)
    {
        if(deep[x]<deep[y])
            swap(x,y);
        for(int i=k; i>=0; i--)
            if(deep[x]-(1<<i)>=deep[y])
                x=dp[x][i];
        if(x==y)
            return x;
        for(int i=k; i>=0; i--)
            if(dp[x][i]!=dp[y][i])
            {
                x=dp[x][i];
                y=dp[y][i];
            }
        if(dp[x][0]==dp[y][0])
            return dp[x][0];
        else
            return -1;
    }
    int main()
    {
        cin>>n;
        memset(head,-1,sizeof(head));
        for(int i=0; i<n; i++)
        {
            cin>>str1>>str2;
            if(mmp[str1]==0)
            {
                mmp[str1]=++sum;
                out[sum]=str1;
            }
            if(mmp[str2]==0)
            {
                mmp[str2]=++sum;
                out[sum]=str2;
            }
            add(mmp[str1],mmp[str2]);
        }
        k=log(sum)/log(2);
        dfs(1,0);
        cin>>q;
        while(q--)
        {
            cin>>str1>>str2;
            if(str1==str2)
                cout<<str2<<endl;
            else if(lca(mmp[str1],mmp[str2])==-1)
                cout<<-1<<endl;
            else
                cout<<out[lca(mmp[str1],mmp[str2])]<<endl;
        }
        return 0;
    }