poj1330(LCA基础题)

求最近公共祖先。

讲解LCA很好的一篇博客

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 1e4 + 10;
int father[maxn], ans[maxn][maxn];
bool vis[maxn];
int flag[maxn];
vector<int> que[maxn];
int N, M;
int T;

struct Edge
{
    int to, next;
}edge[maxn];
int tot, head[maxn];


void add(int a, int b)
{
    edge[tot].to = b;   edge[tot].next = head[a];   head[a] = tot++;
}


void init()
{
    tot = 0;
    memset(head, -1, sizeof(head));
    memset(vis, 0, sizeof(vis));

    for(int i = 1; i <= N; i++)
        father[i] = i;
}


int findfa(int x)
{
    while(x != father[x])
        x = father[x];
    return x;
}


void LCA(int k)
{
    int j, v;
    for(j = head[k]; j != -1; j = edge[j].next)
    {
        v = edge[j].to;
        if(!vis[v])
        {
            LCA(v);
            father[v] = k;
        }
    }
    vis[k] = true;

    int sz = que[k].size();
    int t;
    for(int i = 0; i < sz; i++)
    {
        t = que[k][i];
        if(vis[t])
        {
            int fa = findfa(t);
            ans[k][t] = ans[t][k] = fa;
            return;
        }
    }
}

int main()
{
    cin >> T;
    while(T--)
    {
        cin >> N;
        init();         //init函数里用到了N,注意位置!
        memset(flag, 0, sizeof(flag));
        for(int i = 1; i <= N; i++)
            que[i].clear();


        int a, b;
        for(int i = 1; i <= N - 1; i++)
        {
            scanf("%d%d", &a, &b);
            add(a, b);
            flag[b]++;
        }
        int p, q;
        cin >> p >> q;
        que[p].push_back(q);
        que[q].push_back(p);

        for(int i = 1; i <= N; i++)
        {
            if(!flag[i])
                LCA(i);

        cout << ans[p][q] << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38577732/article/details/89396657
今日推荐