Cod sursa(job #2413300)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 23 aprilie 2019 11:46:01
Problema Obiective Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <cmath>

using namespace std;

ifstream fin("obiective.in");
ofstream fout("obiective.out");

const int NMax = 32000;

int N, M, C[NMax + 5], Viz[NMax + 5], Nr, TT[NMax + 5], A[20][NMax + 5], Lev[NMax + 5], T;

vector <int> G[NMax + 5], GT[NMax + 5], S;

void DFS1(int Nod)
{
    Viz[Nod] = 1;

    for(auto Vecin : G[Nod])
    {
        if(Viz[Vecin] == 0)
            DFS1(Vecin);
    }
    S.push_back(Nod);
}

void DFS2(int Nod)
{
    C[Nod] = Nr;

    for(auto Vecin : GT[Nod])
    {
        if(C[Vecin] == 0)
            DFS2(Vecin);
    }
}

void DFS(int Nod, int Tata)
{
    int cn = C[Nod], ct = C[Tata]; Viz[Nod] = 1;

    if(cn != ct)
        A[0][cn] = ct, Lev[cn] = Lev[ct] + 1;

    for(auto Vecin : G[Nod])
    {
        if(Viz[Vecin] == 0)
            DFS(Vecin, Nod);
    }
}

int Stramos(int Nod, int P)
{
    int k = 0;

    while(P)
    {
        if(P & 1)
            Nod = A[k][Nod];

        k++, P >>= 1;
    }
    return Nod;
}

int LCA(int x, int y)
{
    if(x == y)
        return x;

    if(Lev[x] < Lev[y])
        swap(x, y);

    x = Stramos(x, Lev[x] - Lev[y]);

    if(x == y)
        return x;

    for(int i = log2(Lev[x]); i >= 0; i--)
    {
        if(A[i][x] != A[i][y])
            x = A[i][x], y = A[i][y];
    }
    return A[0][x];
}

int main()
{
    ///Read
    fin >> N >> M;

    for(int i = 1, a, b; i <= M; i++)
    {
        fin >> a >> b;

        G[a].push_back(b);
        GT[b].push_back(a);
    }
    ///Find SCC
    DFS1(1);

    while(S.size())
    {
        int Nod = S.back(); S.pop_back();

        if(C[Nod] == 0) ++Nr, DFS2(Nod);
    }
    ///Make Supergraph
    memset(Viz, 0, sizeof(Viz)); DFS(1, 0);

    ///Calculate acestors
    for(int i = 1; (1 << i) <= Nr; i++)
    {
        for(int j = 1; j <= Nr; j++)
            A[i][j] = A[i - 1][A[i - 1][j]];
    }
    ///Print
    fin >> T;

    for(int i = 1, a, b, x; i <= T; i++)
    {
        fin >> a >> b; a = C[a], b = C[b]; x = LCA(a, b);
        fout << Lev[a] - Lev[x] << '\n';
    }
    fin.close();
    fout.close();

    return 0;
}