Cod sursa(job #3303713)

Utilizator Anul2024Anul2024 Anul2024 Data 17 iulie 2025 14:11:56
Problema Obiective Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.77 kb
#include <fstream>
#include <vector>
#include <queue>
#define dim 32000
using namespace std;
ifstream fin ("obiective.in");
ofstream fout ("obiective.out");
struct mch
{
    int x,y;
};
mch l[2*dim+1];
int n,m,knd,nrctc,nd[dim+1],ctc[dim+1],gr[dim+1],niv[dim+1],t[15][dim+1],nxt[15][dim+1];
bool vis[dim+1];
vector <int> vi[dim+1],vt[dim+1],vn[dim+1],v[dim+1],vnt[dim+1];
queue <int> q;
void read ()
{
    fin>>n>>m;
    for (int i=1; i<=m; i++)
    {
        fin>>l[i].x>>l[i].y;
        vi[l[i].x].push_back (l[i].y);
        vt[l[i].y].push_back (l[i].x);
    }
}
void dfs1 (int nod)
{
    vis[nod]=1;
    for (int i=0; i<(int)vi[nod].size (); i++)
    {
        int vecin=vi[nod][i];
        if (!vis[vecin])
            dfs1 (vecin);
    }
    nd[++knd]=nod;
}
void dfs2 (int nod)
{
    vis[nod]=1;
    ctc[nod]=nrctc;
    for (int i=0; i<(int)vt[nod].size (); i++)
    {
        int vecin=vt[nod][i];
        if (!vis[vecin])
            dfs2 (vecin);
    }
}
void get_ctc ()
{
    for (int i=1; i<=n; i++)
    {
        if (!vis[i])
            dfs1 (i);
    }
    for (int i=1; i<=n; i++)
        vis[i]=0;
    for (int i=n; i>0; i--)
    {
        if (!vis[nd[i]])
        {
            nrctc++;
            dfs2 (nd[i]);
        }
    }
    for (int i=1; i<=n; i++)
        vis[i]=0;
    for (int i=1; i<=m; i++)
    {
        if (ctc[l[i].x]!=ctc[l[i].y])
        {
            vn[ctc[l[i].x]].push_back (ctc[l[i].y]);
            vnt[ctc[l[i].y]].push_back (ctc[l[i].x]);
            gr[ctc[l[i].y]]++;
        }
    }
    n=nrctc;
}
void sort_top ()
{
    t[0][1]=1;
    niv[1]=1;
    q.push (1);
    while (!q.empty ())
    {
        int nod=q.front ();
        q.pop ();
        for (int i=0; i<(int)vn[nod].size (); i++)
        {
            int vecin=vn[nod][i];
            gr[vecin]--;
            if (!gr[vecin])
            {
                niv[vecin]=niv[nod]+1;
                t[0][vecin]=nod;
                v[nod].push_back (vecin);
                q.push (vecin);
            }
        }
    }
    for (int i=1; i<=n; i++)
        vis[i]=0;
}
void dfs3 (int nod)
{
    nxt[0][nod]=nod;
    for (int i=0; i<(int)vnt[nod].size (); i++)
    {
        int vecin=vnt[nod][i];
        if (niv[vecin]<niv[nxt[0][nod]])
            nxt[0][nod]=vecin;
    }
    for (int i=0; i<(int)v[nod].size (); i++)
    {
        int vecin=v[nod][i];
        dfs3 (vecin);
        if (niv[nxt[0][vecin]]<niv[nxt[0][nod]])
            nxt[0][nod]=nxt[0][vecin];
    }
}
void calc ()
{
    for (int p=1; (1<<p)<=n; p++)
    {
        for (int i=1; i<=n; i++)
        {
            t[p][i]=t[p-1][t[p-1][i]];
            nxt[p][i]=nxt[p-1][nxt[p-1][i]];
        }
    }
}
int get_lca (int x,int y)
{
    if (niv[x]<niv[y])
        swap (x,y);
    int dif=niv[x]-niv[y];
    for (int p=14; p>=0; p--)
    {
        if ((dif>>p)&1)
            x=t[p][x];
    }
    for (int p=14; p>=0; p--)
    {
        if (t[p][x]!=t[p][y])
            x=t[p][x],y=t[p][y];
    }
    if (x!=y)
        x=t[0][x];
    return x;
}
int calc (int d,int x)
{
    int sol=0;
    for (int p=14; p>=0; p--)
    {
        if (niv[nxt[p][x]]>d)
        {
            sol+=(1<<p);
            x=nxt[p][x];
        }
    }
    if (niv[x]>d)
        sol++;
    return sol;
}
void solve ()
{
    int q,x,y;
    fin>>q;
    while (q--)
    {
        fin>>x>>y;
        if (ctc[x]==ctc[y])
            fout<<"0\n";
        else
        {
            x=ctc[x];
            y=ctc[y];
            int p=get_lca (x,y);
            fout<<calc (niv[p],x)<<"\n";
        }
    }
}
int main ()
{
    read ();
    get_ctc ();
    sort_top ();
    dfs3 (1);
    calc ();
    solve ();
    return 0;
}