Cod sursa(job #2772264)

Utilizator Edyci123Bicu Codrut Eduard Edyci123 Data 31 august 2021 15:12:21
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#include <bits/stdc++.h>
#define LOG 19
#define NMAX 100010

using namespace std;

ifstream f("ct.in");
ofstream g("ct.out");

int n, m, k, q;
int lg[2 * NMAX], poz[NMAX], depth[NMAX];
pair <int, int> rmq[LOG][2 * NMAX];
vector <int> edges[NMAX];
bitset <NMAX> v, bombed;

struct elem
{
    int x, y, oras;

    bool operator<(const elem& x) const
    {
        return depth[oras] > depth[x.oras];
    }
};

vector <elem> B;

void dfs(int nod, int niv)
{
    v[nod] = 1;
    rmq[0][++k].second = nod;
    rmq[0][k].first = niv;
    depth[nod] = niv;
    poz[nod] = k;
    for(auto child : edges[nod])
        if(!v[child])
        {
            dfs(child, niv + 1);
            rmq[0][++k].second = nod;
            rmq[0][k].first = niv;
        }
}

void dfsB(int nod)
{
    bombed[nod] = 1;
    for(auto child : edges[nod])
        if(depth[child] == depth[nod] + 1)
            dfsB(child);
}

int lca(int x, int y)
{
    x = poz[x];
    y = poz[y];
    if(x > y)
        swap(x, y);
    int k = lg[y - x];
    pair <int, int> ans = min(rmq[k][x], rmq[k][y - (1 << k) + 1]);
    return ans.second;
}


int main()
{
    f >> q;

    for(int i = 1; i < 2 * NMAX; i++)
        lg[i] = lg[i / 2] + 1;

    for(; q; q--)
    {
        f >> n >> m;
        for(int i = 1; i <= n - 1; i++)
        {
            int x, y;
            f >> x >> y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        dfs(1, 0);

        for(int i = 1; i <= lg[k]; i++)
            for(int j = 1; j + (1 << i) - 1 <= k; j++)
                rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);

        for(int i = 1; i <= m; i++)
        {
            int x, y;
            f >> x >> y;
            int z = lca(x, y);
            B.push_back({x, y, z});
        }
        sort(B.begin(), B.end());

        int nr = 0;
        for(auto b : B)
            if(!bombed[b.x] && !bombed[b.y])
                dfsB(b.oras), nr++;

        for(int i = 1; i <= n; i++)
            edges[i].clear();
        B.clear();
        v.reset();
        bombed.reset();
        k = 0;
        g << nr << "\n";
    }

    return 0;
}