Pagini recente » Cod sursa (job #470583) | Cod sursa (job #2489041) | Cod sursa (job #910086) | Cod sursa (job #2184801) | Cod sursa (job #3225001)
#include <bits/stdc++.h>
using namespace std;
///----------TOGGLES
#define FIO
#define LONGER
//#define TESTS
///---------
#ifdef LONGER
#define int long long
#endif // LONGER
#ifdef FIO
const string fname="obiective";
ifstream in(fname+".in");
ofstream out(fname+".out");
#define cin in
#define cout out
#endif // FIO
///--------
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
///-------STL++-----
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) x.size()
#define pb(x,y) x.push_back(y)
#define mp(x,y) make_pair(x,y)
#define fr(i,n) for(int i=1;i<=n;i++)
using ll = long long;
using ld = long double;
using pii = pair<int,int>;
using pdd = pair<double, double>;
using veci = vector<int>;
using vecp = vector<pii>;
template<typename T> using PQ = priority_queue<T, vector<T>, greater<T> >;
///-----CODE GOES HERE-----
const int maxb = 21;
const int maxn = 32005;
int n,m, q;
int t[maxb][maxn];
int ret[maxb][maxn];
veci g[maxn], rg[maxn];
veci arb[maxn];
veci auxg[maxn];
int vis[maxn];
int col[maxn], ck;
int ord[maxn], invord[maxn], ordk;
int h[maxn];
int besth(int a, int b)
{
return h[a]<b[h]?a:b;
}
void sortTop(int nod)
{
vis[nod]=1;
for(auto e:g[nod])
{
if(vis[e]!=1) sortTop(e);
}
ord[++ordk]=nod;
}
void colGraf(int nod, int c)
{
//cerr<<"here "<<nod<<' '<<c<<'\n';
col[nod]=c;
vis[nod]=3;
for(auto e:rg[nod]) if(vis[e]!=3)
{
colGraf(e, c);
}
}
void buildArb(int nod)
{
//cerr<<"here "<<nod<<'\n';
vis[nod]=2;
for(auto e:g[nod])
{
if(vis[e]!=2) arb[nod].push_back(e), buildArb(e);
}
}
void buildDinamici(int nod)
{
for(int i=1;i<maxb;i++) t[i][nod]=t[i-1][t[i-1][nod]];
for(auto e:arb[nod])
{
t[0][e]=nod;
h[e]=h[nod]+1;
buildDinamici(e);
}
ret[0][nod]=nod;
for(auto e:rg[nod]) ret[0][nod]=besth(ret[0][nod], e);
for(auto e:arb[nod]) ret[0][nod]=besth(ret[0][nod], ret[0][e]);
}
int lca(int a, int b)
{
if(h[a]<h[b]) swap(a,b);
for(int step=maxb-1; step>=0;step--)
{
if(h[t[step][a]]>=h[b]) a=t[step][a];
}
//cerr<<"here! "<<a<<' '<<h[a]<<','<<b<<' '<<h[b]<<'\n';
if(a==b) return b;
for(int step=maxb-1;step>=0;step--)
{
if(t[step][a]!=t[step][b]) a=t[step][a], b=t[step][b];
}
return t[0][a];
}
int retDist(int a, int b)
{
if(h[a]<=h[b]) return 0;
int ans=0;
for(int step=maxb-1; step>=0;step--)
{
if(h[ret[step][a]]>h[b]) ans+=(1<<(step)), a=ret[step][a];
}
return ans+1;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
pb(g[a],b);
pb(rg[b],a);
}
for(int i=1;i<=n;i++) if(vis[i]!=1) sortTop(i);
reverse(ord+1, ord+n+1);
for(int i=1;i<=n;i++) if(vis[ord[i]]!=3) colGraf(ord[i], ++ck);
for(int i=1;i<=n;i++)
{
for(auto e:g[i]) if(col[i]!=col[e])
{
auxg[col[i]].push_back(col[e]);
}
}
for(int i=1;i<=n;i++) g[i].clear(), rg[i].clear();
for(int i=1;i<=ck;i++)
{
for(auto e:auxg[i])
{
g[i].push_back(e);
rg[e].push_back(i);
}
}
n=ck;
int root=0;
ordk=0;
for(int i=1;i<=n;i++)
{
if(rg[i].size()==0)
{
root=i;
sortTop(i);
break;
}
}
reverse(ord+1, ord+n+1);
for(int i=1;i<=n;i++) invord[ord[i]]=i;
for(int i=1;i<=n;i++) sort(all(g[i]), [&](int a, int b){return invord[a]<invord[b];});
buildArb(root);
h[0]=-1;
buildDinamici(root);
for(int i=1;i<maxb;i++)
{
for(int j=1;j<=n;j++)
{
ret[i][j]=ret[i-1][ret[i-1][j]];
}
}
cin>>q;
int a,b;
for(int i=1;i<=q;i++)
{
cin>>a>>b;
a=col[a];
b=col[b];
int c=lca(a,b);
cout<<retDist(a,c) +retDist(c,b)<<'\n';
}
}
///---MAIN FUNC-------
int32_t main()
{
IOS;
int t=1;
#ifdef TESTS
cin>>t;
#endif // TESTS
while(t--)
{
solve();
}
return 0;
}