Pagini recente » Cod sursa (job #933681) | Cod sursa (job #571470) | Cod sursa (job #3243219) | Cod sursa (job #3327476) | Cod sursa (job #3303713)
#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;
}