Cod sursa(job #728293)

Utilizator mihai995mihai995 mihai995 Data 28 martie 2012 16:58:28
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <stack>
using namespace std;

const int N=32005,LG=16;
int T[LG][N],comp[N],depth[N],n,nr;
bool use[N];
vector<int> a[N],adj[N],trans[N];
stack<int> S;

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

inline int max(int a,int b)
{
    return a>b ? a : b;
}

void add(vector<int> &a,vector<int> &b)
{
    for (vector<int>::iterator i=b.begin();i!=b.end();i++)
        if (comp[*i]!=nr)
            a.push_back(*i);
}

void dfs(stack<int> &S,int x)
{
    use[x]=true;
    for (vector<int>::iterator i=adj[x].begin();i!=adj[x].end();i++)
        if (!use[*i])
            dfs(S,*i);
    S.push(x);
}

void dfs(int x)
{
    use[x]=true;
    comp[x]=nr;
    for (vector<int>::iterator i=trans[x].begin();i!=trans[x].end();i++)
        if (!use[*i])
            dfs(*i);
    add(a[nr],adj[x]);
}

void edit(vector<int>& a)
{
    for (vector<int>::iterator i=a.begin();i!=a.end();i++)
        (*i)=comp[*i];
}

void mark(vector<int> &a)
{
    for (vector<int>::iterator i=a.begin();i!=a.end();i++)
        use[*i]=true;
}

int ctc()
{
    int x;
    for (int i=1;i<=n;i++)
        if (!use[i])
            dfs(S,i);
    memset(use,false,sizeof(use));
    while (!S.empty())
    {
        x=S.top();
        S.pop();
        if (!use[x])
        {
            ++nr;
            dfs(x);
        }
    }
    for (int i=1;i<=nr;i++)
        edit(a[i]);
    memset(use,false,sizeof(use));
    for (int i=1;i<=nr;i++)
        mark(a[i]);
    for (int i=1;i<=nr;i++)
        if (!use[i])
            return i;
    return 0;
}

void dfs(int x,int D)
{
    use[x]=true;
    depth[x]=D;
    for (vector<int>::iterator i=a[x].begin();i!=a[x].end();i++)
        if (!use[*i])
        {
            dfs(*i,D+1);
            T[0][*i]=x;
        }
}

void stramosi()
{
    for (int i=1;i<LG;i++)
        for (int j=1;j<=nr;j++)
            T[i][j]=T[i-1][T[i-1][j]];
}

int tata(int x,int L)
{
    for (int i=LG-1;i>=0;i--)
        if ((1<<i)<=L)
        {
            x=T[i][x];
            L-=1<<i;
        }
    return x;
}

int lca(int x,int y)
{
    if (depth[x]<depth[y])
        y=tata(y,depth[y]-depth[x]);
    else
        x=tata(x,depth[x]-depth[y]);
    if (x==y)
        return x;
    for (int i=LG-1;i>=0;i--)
        if (T[i][x] && T[i][x]!=T[i][y])
        {
            x=T[i][x];
            y=T[i][y];
        }
    return T[0][x];
}

int calc(int x,int y)
{
    x=comp[x];
    y=comp[y];
    return depth[x]-depth[lca(x,y)];
}

int main()
{
    int m,x,y;
    in>>n>>m;
    while (m--)
    {
        in>>x>>y;
        adj[x].push_back(y);
        trans[y].push_back(x);
    }
    x=ctc();
    memset(use,false,sizeof(use));
    dfs(x,0);
    stramosi();
    in>>m;
    while (m--)
    {
        in>>x>>y;
        out<<calc(x,y)<<"\n";
    }
    return 0;
}