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;

    }
}

 

posted on 2014-11-04 07:49  一个西瓜  阅读(205)  评论(0编辑  收藏  举报

导航