Cod sursa(job #2427316)

Utilizator retrogradLucian Bicsi retrograd Data 31 mai 2019 16:04:21
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;

vector<int> link, start, finish, lca, depth;
vector<vector<int>> graph;
vector<vector<pair<int, int>>> qrs;
int timer;

int Find(int x) {
    if (link[x] == -1) return x;
    return link[x] = Find(link[x]);
}

void Process(int node, int par) {
    start[node] = timer++;
    for (auto vec : graph[node]) {
        if (vec == par) continue;
        depth[vec] = 1 + depth[node];
        Process(vec, node);
        link[Find(vec)] = Find(node);
    }
    finish[node] = timer;
    for (auto itr : qrs[node]) {
        int oth = itr.first;
        if (finish[oth] != -1)
            lca[itr.second] = Find(oth);
    }
}

int main() {
    ifstream cin("ct.in");
    ofstream cout("ct.out");

    int t; cin >> t;
    while (t--) {
        int n, k; cin >> n >> k;
        link.assign(n, -1); 
        start.assign(n, -1);
        finish.assign(n, -1);
        graph.assign(n, {});
        qrs.assign(n, {});
        lca.assign(k, -1);
        depth.assign(n, 0);
        timer = 0;
        
        for (int i = 1; i < n; ++i) {
            int a, b; cin >> a >> b; --a; --b;
            graph[a].push_back(b);
            graph[b].push_back(a);
        }
        vector<int> order(k);
        for (int i = 0; i < k; ++i) {
            int a, b; cin >> a >> b; --a; --b;
            qrs[a].emplace_back(b, i);
            qrs[b].emplace_back(a, i);
            order[i] = i;
        }

        Process(0, -1);
        sort(order.begin(), order.end(), [&](int a, int b) {
            return depth[lca[a]] > depth[lca[b]];        
        });
        
        multimap<int, int> to_solve;
        vector<bool> solved(k, false);
        for (int i = 0; i < n; ++i) {
            for (auto itr : qrs[i]) {
                to_solve.emplace(start[i], itr.second);
            }
        }
        
        int ans = 0;
        for (auto i : order) {
            if (solved[i]) continue;
            ans += 1;
            int bomb = lca[i];
            auto it = to_solve.lower_bound(start[bomb]);
            while (it != to_solve.end() && it->first <= finish[bomb]) {
                solved[it->second] = true;
                it = to_solve.erase(it);
            }
        }

        cout << ans << endl;
    }
    return 0;
}