Pagini recente » Cod sursa (job #1344491) | Cod sursa (job #2887302) | Cod sursa (job #2544892) | Cod sursa (job #758015) | Cod sursa (job #3225165)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("obiective.in");
ofstream fout("obiective.out");
const int nmax = 32003;
vector<int> g[nmax],rg[nmax];
vector<int> adj[nmax];
vector<int> aux;
int n,m,t;
int viz[nmax];
int color[nmax];
void dfs1(int i)
{
if(viz[i] == 1) return;
viz[i] = 1;
for(auto pi : g[i])
{
dfs1(pi);
}
aux.push_back(i);
}
void dfs2(int i, int clr)
{
if(viz[i] == 2) return;
viz[i] = 2;
color[i] = clr;
for(auto pi : rg[i]) dfs2(pi,clr);
}
int root;
vector<int> toposort;
int grad[nmax];
int pos_in_toposort[nmax];
void sortTop(int i)
{
if(viz[i]) return;
viz[i] = 1;
for(auto pi: adj[i]) sortTop(pi);
toposort.push_back(i);
}
vector<int> verzi[nmax],rosii[nmax];
int depth[nmax];
void dfs_depth(int i, int tata)
{
if(depth[i] != 0) return;
depth[i] = depth[tata] + 1;
for(auto pi : adj[i])
{
dfs_depth(pi,i);
}
}
const int pmax = 17;
int lift[nmax][pmax];
void dfs_build_tree(int i)
{
for(auto pi : adj[i])
{
if(depth[pi] == depth[i] + 1)
{
verzi[i].push_back(pi);
lift[pi][0] = i;
dfs_build_tree(pi);
}
}
}
int tin[nmax],tout[nmax];
int timp = 0;
void dfs_lift(int i)
{
tin[i] = timp ++;
for(int p = 1; p < pmax; p++)
{
lift[i][p] = lift[lift[i][p-1]][p-1];
}
for(auto pi: verzi[i])
{
dfs_lift(pi);
}
tout[i] = timp ++;
}
bool is_ancestor(int nod, int tata)
{
return tin[tata] <= tin[nod] && tout[nod] <= tout[tata];
}
int lca(int a, int b)
{
if(is_ancestor(a,b)) return b;
if(is_ancestor(b,a)) return a;
for(int p = pmax - 1; p >= 0; p--)
{
if(!is_ancestor(b,lift[a][p]))
a = lift[a][p];
}
return lift[a][0];
}
int dp[nmax][pmax];
int best_depth(int a, int b)
{
return depth[a] < depth[b] ? a : b;
}
void dfs_dp0(int i)
{
for(auto pi: verzi[i]) dfs_dp0(pi);
dp[i][0] = i;
for(auto pi: rosii[i])
{
dp[i][0] = best_depth(pi,dp[i][0]);
}
for(auto pi: verzi[i])
{
dp[i][0] = best_depth(dp[i][0],dp[pi][0]);
}
}
void dfs_dp(int i, int p)
{
dp[i][p] = dp[dp[i][p-1]][p-1];
for(auto pi: verzi[i])
{
dfs_dp(pi,p);
}
}
int main()
{
fin>>n>>m;
for(int i=1; i<=m; i++)
{
int a,b; fin>>a>>b;
g[a].push_back(b);
rg[b].push_back(a);
}
for(int i=1; i<=n; i++) dfs1(i);
reverse(aux.begin(),aux.end());
int clr = 1;
for(auto i: aux)
{
if(viz[i] == 2) continue;
dfs2(i,clr);
clr++;
}
clr --;
map<pair<int,int> , bool> muchii;
for(int i=1; i<=n; i++)
{
for(auto pi: g[i])
{
if(color[pi] == color[i]) continue;
if(muchii[{color[i],color[pi]}] == 0)
{
muchii[{color[i],color[pi]}] = 1;
adj[color[i]].push_back(color[pi]);
rosii[color[pi]].push_back(color[i]);
}
}
}
n = clr;
for(int i=1; i<=n; i++)
{
if(rosii[i].size() == 0) root = i;
}
memset(viz,0,sizeof viz);
sortTop(root);
reverse(toposort.begin(),toposort.end());
for(int i=0; i<n; i++) pos_in_toposort[toposort[i]] = i;
for(int i=1; i<=n; i++)
{
sort(adj[i].begin(),adj[i].end(),[&](int a, int b) {return pos_in_toposort[a] < pos_in_toposort[b];});
}
dfs_depth(root,0);
dfs_build_tree(root);
lift[root][0] = root;
dfs_lift(root);
dfs_dp0(root);
for(int p = 1; p<pmax; p++)
{
dfs_dp(root,p);
}
fin>>t;
for(int i=1; i<=t; i++)
{
int a,b; fin>>a>>b;
a = color[a]; b = color[b];
int LCA = lca(a,b);
if(LCA == a) fout<<"0\n";
else
{
int cost_a = 0;
for(int p = pmax - 1; p >=0; p--)
{
if(depth[dp[a][p]] > depth[LCA])
{
cost_a += (1<<p);
a = dp[a][p];
}
}
fout<<cost_a + 1<<"\n";
}
}
return 0;
}