hiho13周暴力求lca

先求一个节点的所有先人,然后从另外一个节点开始向上找,找到第一个共同的先人就是最近公共祖先。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<map>

using namespace std;



int fathe[1222];

int color[122];

int father[1222];

int getfather(int x)

{

    if (x != fathe[x]) fathe[x] = getfather(fathe[x]);

    return fathe[x];

}



void add(int a, int b)

{

    int fa = getfather(a); int fb = getfather(b);

    fathe[fa] = fb;

}



void Find(int x)

{

    while (father[x]!=-1&&father[x]!=x){

        color[x] = 1;

        x = father[x];

    }

    color[x] = 1;

}



int find1(int x)

{

    while(father[x]!=-1&&father[x]!=x){

        if(color[x]) return x;

        x = father[x] ;

    }

    return x;

}



int main()

{

    int n;

    string a,b;

    //memset(color,0,sizeof(color));

    memset(father,-1,sizeof(father));

    map<string, int> m;

    map<int, string > m1;

    cin >> n;

    int sum = 1;

    for(int i =1;i<=1000;i++)

        fathe[i] = i;

    for (int i = 0; i < n; i++){

        cin >> a >> b; int c; int d;

        if (!m.count(a)) m[a] = sum, m1[sum] = a,sum++;

        if (!m.count(b)) m[b] = sum, m1[sum] = b,sum++;

        c = m[a]; d = m[b];

        father[d] = c;

        add(d, c);

    }

    int q;

    cin >> q;

    for (int i = 0; i < q; i++){

        memset(color,0,sizeof(color));

        cin >> a >> b;

        if(!m.count(a)||!m.count(b)){

            if(a==b) cout<<a<<endl;

        else

            cout<<-1<<endl;

            continue;

        }

        int c = m[a]; int d = m[b];

        int fc = getfather(c); int fd = getfather(d);

        if (fc != fd){

            printf("-1\n");

            continue;

        }

        Find(c);

        cout<<m1[find1(d)]<<endl;



    }

}

 

你可能感兴趣的:(ca)