Cod sursa(job #2050872)

Utilizator vladdy47Bucur Vlad Andrei vladdy47 Data 28 octombrie 2017 11:46:07
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 kb
# include <bits/stdc++.h>

using namespace std;

const int Nmax = 32001 + 5;

struct per
{
    int first, second, third;
};

per ans;
vector <int> G[Nmax];

int rmq[20][2 * Nmax], Log[2 * Nmax], euler[2 * Nmax], root[Nmax], score[Nmax], node_pos[Nmax], depth[Nmax];
int x, y, i, j, n, m, N, Root;

void dfs(int node, int lvl)
{
    euler[++N] = node, depth[node] = lvl, node_pos[node] = N;

    for (auto &it: G[node])
    {
        dfs(it, lvl + 1);
        euler[++N] = node;
    }
}

void build_rmq()
{
    Log[1] = 0;

    for (i = 2;  i <= N; ++i)
        Log[i] = Log[i / 2] + 1;

    for (i = 1; i <= N; ++i)
        rmq[0][i] = euler[i];

    for (i = 1;  i <= Log[N]; ++i)
        for (j = 1; j <= N - (1 << (i - 1)); ++j)
        {
            int a = rmq[i - 1][j], b = rmq[i - 1][j + (1 << (i - 1))];
            if (depth[a] < depth[b]) rmq[i][j] = a;
            else rmq[i][j] = b;
        }
}

int LCA(int x, int y)
{
    x = node_pos[x], y = node_pos[y];
    if (x > y) swap(x, y);

    int len = Log[y - x + 1];
    int a = rmq[len][x], b = rmq[len][y - (1 << len) + 1];

    if (depth[a] < depth[b]) return a;

    return b;
}

int main ()
{
    freopen("concurs.in", "r", stdin);
    freopen("concurs.out", "w", stdout);

    scanf("%d %d\n", &n, &m);

    for (i = 1; i <= n; ++i)
        scanf("%d ", &score[i]);

    for (i = 1; i < n; ++i)
    {
        scanf("%d %d\n", &x, &y);
        G[x].push_back(y);
        root[y] = 1;
    }

    for (i = 1; i <= n; ++i)
        if (!root[i])
        {
            Root = i;
            break;
        }

    dfs(Root, 0);
     assert (N == 2 * n - 1);
    build_rmq();

    ans.first = -INT_MAX, ans.second = INT_MAX, ans.third = INT_MAX;

    for (i = 1; i <= m; ++i)
    {
        scanf("%d %d\n", &x, &y);

        int val = LCA(x, y);
        int sol = score[val];

        if (sol == ans.first)
        {
            if (ans.second == x) ans.third = y;
            if (ans.second > x) ans.second = x, ans.third = y;
        }

        if (sol > ans.first)
            ans.first = sol, ans.second = x, ans.third = y;
    }

    printf("%d %d %d\n", ans.first, ans.second, ans.third);

    return 0;
}