Cod sursa(job #1468816)

Utilizator tudi98Cozma Tudor tudi98 Data 7 august 2015 00:38:21
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.5 kb
#include <fstream>
#include <vector>
#include <stack>
using namespace std;

const int Nmax = 32001;

int N,M,Q;
vector<int> Adj[Nmax];
vector< vector<int> > Component;
stack<int> S;
bool seen[Nmax];
bool in_stack[Nmax];
int comp[Nmax];
int lowlink[Nmax];
int idx[Nmax];
int have[Nmax];
int Idx = 0;
int SCC = 0;
bool comes[Nmax];

vector<int> G[Nmax];          // every node is a connected component
int lvl[Nmax];
int T[16][Nmax];

void Tarjan(int node)
{
    ++Idx;
    lowlink[node] = Idx;
    idx[node] = Idx;
    seen[node] = 1;
    in_stack[node] = 1;
    S.push(node);

    for(vector<int>::iterator it = Adj[node].begin(); it != Adj[node].end(); ++it)
    {
        if(!seen[*it])
        {
            Tarjan(*it);
            lowlink[node] = min(lowlink[node],lowlink[*it]);
        }
        else if(in_stack[*it])
            lowlink[node] = min(lowlink[node],lowlink[*it]);
    }

    if(lowlink[node] == idx[node])
    {
        ++SCC;
        Component.push_back(vector<int>());
        while(S.top() != node)
        {
            comp[S.top()] = SCC;
            in_stack[S.top()] = 0;
            Component.back().push_back(S.top());
            S.pop();
        }

        comp[node] = SCC;
        in_stack[node] = 0;
        Component.back().push_back(node);
        S.pop();
    }
}

void dfs(int node)
{
    for(vector<int>::iterator it = G[node].begin(); it != G[node].end(); it++)
    {
        lvl[*it] = lvl[node] + 1;
        T[0][*it] = node;
        dfs(*it);
    }
}

void Build_LCA()
{
    for(int i = 1; (1 << i) <= N; i++)
        for(int j = 1; j <= SCC; j++)
            T[i][j] = T[i-1][T[i-1][j]];
}

int lca(int x,int y)
{
    if(lvl[x] < lvl[y])
        swap(x,y);

    int log1,log2;
    for(log1 = 1; (1 << log1) <= lvl[x]; log1++);
    for(log2 = 1; (1 << log2) <= lvl[y]; log2++);
    --log1,--log2;

    for(;lvl[x] > lvl[y]; --log1)
        if(lvl[y] <= lvl[T[log1][x]])
            x = T[log1][x];

    if(x == y) return x;

    for(; log2; --log2)
        if(T[log2][x] != T[log2][y])
        {
            x = T[log2][x];
            y = T[log2][y];
        }

    return T[0][x];
}

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

    fin >> N >> M;
    for(int i = 1; i <= M; i++)
    {
        int a,b;
        fin >> a >> b;
        Adj[a].push_back(b);
    }

    for(int i = 1; i <= N; i++)
        if(!seen[i])
            Tarjan(i);

//    for(int i = 1; i <= N; i++)
//        fout << comp[i] << "\n";

    for(int i = 1; i <= SCC; i++)
        for(int j = 0; j < Component[i-1].size(); j++)
            for(vector<int>::iterator it = Adj[Component[i-1][j]].begin(); it != Adj[Component[i-1][j]].end(); it++)
                if(have[comp[*it]] == i || comp[*it] == i)
                    continue;
                else
                {
                    G[i].push_back(comp[*it]);
                    comes[comp[*it]] = 1;
                    have[comp[*it]] = i;
                    //fout << i << " -> " << comp[*it] << "\n";
                }

    int root;
    for(int i = 1; i <= SCC; i++)
        if(!comes[i])
        {
            root = i;
            break;
        }

    dfs(root);
    Build_LCA();

    fin >> Q;
    while(Q--)
    {
        int Gara,Muzeu;
        fin >> Gara >> Muzeu;
        Gara = comp[Gara];
        Muzeu = comp[Muzeu];
        fout << lvl[Gara] - lvl[lca(Gara,Muzeu)] << "\n";
    }
}