Cod sursa(job #1326675)

Utilizator sebinechitasebi nechita sebinechita Data 25 ianuarie 2015 20:18:25
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.44 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
ifstream fin("ct.in");
ofstream fout("ct.out");
#define MAX 100010

typedef vector<int> :: iterator iter;
vector<int> G[MAX];
typedef vector<pair<int, int> > :: iterator iti;
vector<pair<int, int> > sol, v[MAX];
int st[MAX], s, dr, n, d[MAX], ap[MAX], lg, dad[MAX];
bool viz[MAX];
int RMQ[2 * MAX][19];

const unsigned maxb = 8192;
unsigned ptr = maxb - 1;
char buf[maxb];

int getInt()
{
    int rez = 0;
    while(!(buf[ptr] >= '0' && buf[ptr] <= '9'))
    {
        if(++ptr >= maxb)
        {
            fin.read(buf, maxb);
            ptr = 0;
        }
    }
    while((buf[ptr] >= '0' && buf[ptr] <= '9'))
    {
        rez = rez * 10 + buf[ptr] - '0';
        if(++ptr >= maxb)
        {
            fin.read(buf, maxb);
            ptr = 0;
        }
    }
    return rez;
}

void df(int nod, int mom)
{
    dad[nod] = mom;
    RMQ[++dr][0] = nod;
    ap[nod] = dr;
    d[nod] = ++lg;
    for(iter it = G[nod].begin() ; it != G[nod].end() ; it++)
    {
        if(*it == mom)
            continue;
        df(*it, nod);
        RMQ[++dr][0] = nod;
    }

    lg--;
}

int lca(int a, int b)
{
    a = ap[a];
    b = ap[b];
    if(a > b)
        swap(a, b);
    int k = log2(b - a + 1);
    if(d[RMQ[a][k]] < d[RMQ[b - (1 << k) + 1][k]])
        return RMQ[a][k];
    else
        return RMQ[b - (1 << k) + 1][k];
}

void mark(int nod)
{
    viz[nod] = 1;
    for(iter it = G[nod].begin() ; it != G[nod].end() ; it++)
        if(!viz[*it] && *it != dad[nod])
            mark(*it);
}

void init()
{
    s = 0;
    dr = 0;
    memset(ap, 0, sizeof(ap));
    memset(st, 0, sizeof(st));
    memset(viz, 0, sizeof(viz));
    memset(d, 0, sizeof(d));
    memset(RMQ, 0, sizeof(RMQ));
    for(int i = 1 ; i <= n ; i++)
    {
        G[i].clear();
        v[i].clear();
    }
    sol.clear();
}
int main()
{
    int t, i, x, y, j, k;
    t = getInt();
    while(t--)
    {
        n = getInt();
        k = getInt();
        init();
        for(i = 1 ; i < n ; i++)
        {
            x = getInt();
            y = getInt();
            G[x].push_back(y);
            G[y].push_back(x);
        }
        df(1, 0);
        for(j = 1 ;(1 << j) <= dr ; j++)
        {
            for(i = 1 ; i + (1 << j) - 1 <= dr ; i ++)
            {
                if(d[RMQ[i][j - 1]] > d[RMQ[i + (1 << (j - 1))][j - 1]])
                {
                    RMQ[i][j] = RMQ[i + (1 << (j - 1))][j - 1];
                }
                else
                {
                    RMQ[i][j] = RMQ[i][j - 1];
                }
            }
        }
        for(i = 1 ; i <= k ; i++)
        {
            x = getInt();
            y = getInt();
            int l = lca(x, y);
            v[l].push_back(make_pair(x, y));
            sol.push_back(make_pair(-d[l], l));
        }
        sort(sol.begin(), sol.end());
        for(iti it = sol.begin() ; it != sol.end() ; it++)
        {
            int nod = it->second;
            if(!viz[nod])
                for(iti ite = v[nod].begin() ; ite != v[nod].end() ; ite++)
                    if(!viz[ite->first] && !viz[ite->second])
                    {
                        mark(nod);
                        s++;
                    }
        }
        fout << s << "\n";
    }
}