Pagini recente » Cod sursa (job #2190004) | Cod sursa (job #755496) | Cod sursa (job #574290) | Cod sursa (job #1799626) | Cod sursa (job #1950195)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int nmax=32005;
vector<int> v[nmax],V[nmax],newv[nmax],lista[nmax],vt[nmax],VP[nmax];
int p[2*nmax],viz[nmax],rad[nmax],c[nmax],tt[nmax],anc[20][nmax],first[nmax],st[nmax],dr[nmax];
int n,m,q,i,k,x,C,nod,t,j,R,unu,doi,a,b,niv,dif,idx,cost,pu,newn;
void dfs(int x)
{
viz[x]=1;
for(int i=0;i<v[x].size();i++)
if(!viz[v[x][i]])
dfs(v[x][i]);
k++;p[k]=x;
}
void dfst(int x)
{
viz[x]=0;c[x]=C;lista[C].push_back(x);
for(int i=0;i<vt[x].size();i++)
if(viz[vt[x][i]])
dfst(vt[x][i]);
}
void build_ctc()
{
for(x=1;x<=n;x++)
if(!viz[x])
dfs(x);
for(x=n;x>=1;x--)
{
nod=p[x];
if(viz[nod])
{
C++;
dfst(nod);
}
}
}
void dfsortop(int x)
{
viz[x]=1;
for(int i=0;i<V[x].size();i++)
if(!viz[V[x][i]])
dfsortop(V[x][i]);
k++;p[k]=x;
}
void dfsfreetree(int x)
{
idx++;st[x]=idx;
for(int i=0;i<VP[x].size();i++)
dfsfreetree(VP[x][i]);
dr[x]=idx;
}
void build_trees()
{
for(i=1;i<=C;i++)
rad[i]=1;
for(i=1;i<=C;i++)
for(j=0;j<lista[i].size();j++)
for(k=0;k<v[lista[i][j]].size();k++)
if(c[v[lista[i][j]][k]]!=i)
{
V[i].push_back(c[v[lista[i][j]][k]]);
rad[c[v[lista[i][j]][k]]]=0;
}
k=0;
for(x=1;x<=C;x++)
if(!viz[i])
dfsortop(x);
for(i=C;i>=1;i--)
{
x=p[i];
for(j=0;j<V[x].size();j++)
if(!tt[V[x][j]])
{anc[0][V[x][j]]=x;}
}//arborele pe care il folosim cand avem cel putin o strada de reorientat
for(i=1;i<=C;i++)
{
x=p[i];
for(j=0;j<V[x].size();j++)
if(!tt[V[x][j]])
{tt[V[x][j]]=x;}
}//arborele folosit cand nu trebuie sa reorientam muchii
idx=0;//k e folosit la euler la celalt arbore
for(i=1;i<=C;i++)
{VP[tt[i]].push_back(i);viz[i]=0;tt[i]=0;}
dfsfreetree(R);
}
void build_dp()
{
for(i=1;(1<<i)<=C;i++)
for(j=1;j<=C;j++)
anc[i][j]=anc[i-1][anc[i-1][j]];
}
int main()
{
ifstream f("obiective.in");
ofstream g("obiective.out");
f>>n>>m;
for(i=1;i<=m;i++)
{
f>>a>>b;
v[a].push_back(b);
vt[b].push_back(a);
}
build_ctc();
build_trees();
build_dp();
f>>q;
for(i=1;i<=q;i++)
{
f>>a>>b;
if(st[c[a]]<=st[c[b]]&&st[c[b]]<=dr[c[a]]) g<<"0\n";
else
{
a=c[a];b=c[b];cost=0;
for(pu=17;pu>=0;pu--)
{
newn=anc[pu][a];
if(newn!=0&&(!(st[newn]<=st[b]&&st[b]<=dr[newn])))
{
cost+=(1<<pu);
a=newn;
}
}
cost++;
g<<cost<<'\n';
}
}
return 0;
}