Pagini recente » Cod sursa (job #30236) | Cod sursa (job #2133381) | Cod sursa (job #717600) | Cod sursa (job #1276244) | Cod sursa (job #2730678)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#define Min(a, b) (((a)>(b))?(b):(a))
const int N = 1e5 + 5;
std::vector<int>g[N], gt[N], l[N];
int st[N], c[N], k;
int f_app[N], rmq[25][N], mn[25][N], e;
bool viz[N];
void dfs1(int node) {
for(int to:g[node]) if(!viz[to]) {
viz[to] = true;
dfs1(to);
}
st[++st[0]] = node;
}
void dfs2(int node) {
for(int to:gt[node]) if(!viz[to]) {
viz[to] = true;
c[to] = k;
dfs2(to);
}
}
void euler_tour(int node = 1) {
viz[node] = true;
mn[0][++e] = node;
f_app[node] = e;
std::sort(l[node].begin(), l[node].end());
for(int to:l[node]) if(!viz[to]) {
euler_tour(to);
mn[0][++e] = node;
rmq[0][node] = Min(rmq[0][node], rmq[0][to]);
}
}
int lca(int from, int to) {
from = f_app[from], to = f_app[to];
if(from>to) std::swap(from, to);
int p2;
if(to==from) p2 = 0;
else p2 = (int)log2(to-from);
return Min(mn[p2][from], mn[p2][to-(1<<p2)+1]);
}
int solve(int from, int to) {
int ans = 1;
for(int i=(int)log2(k);i>=0;i--) if(rmq[i][from] > to) {
from = rmq[i][from];
ans+=(1<<i);
}
return ans;
}
int main() {
std::ifstream fin("obiective.in");
std::ofstream fout("obiective.out");
int n, m, q, from, to;
fin>>n>>m;
for(int i=1;i<=m;i++) {
fin>>from>>to;
g[from].push_back(to);
gt[to].push_back(from);
}
for(int i=1;i<=n;i++) if(!viz[i]) viz[i] = 1, dfs1(i);
for(int i=1;i<=n;i++) viz[i] = false;
for(int i=n;i>=1;i--) if(!viz[st[i]]) viz[st[i]] = 1, c[st[i]] = ++k, dfs2(st[i]);
for(int i=1;i<=k;i++) rmq[0][i] = i;
for(int i=1;i<=n;i++)
for(int to:g[i])
if(c[to]!=c[i]) {
l[c[i]].push_back(c[to]);
rmq[0][c[to]] = Min(rmq[0][c[to]], c[i]);
}
for(int i=1;i<=k;i++) viz[i] = false;
euler_tour();
for(int j=1;(1<<j)<=k;j++)
for(int i=1;i<=k;i++)
rmq[j][i] = rmq[j-1][rmq[j-1][i]];
for(int j=1;(1<<j)<=e;j++)
for(int i=1;i+(1<<j)-1<=e;i++)
mn[j][i] = Min(mn[j-1][i], mn[j-1][i+(1<<(j-1))]);
fin>>q;
while(q--) {
fin>>from>>to;
from = c[from], to = c[to];
if(from==to) {
fout<<"0\n";
continue;
}
int Lca = lca(from, to);
if(from==Lca) fout<<"0\n";
else fout<<solve(from, Lca)<<"\n";
}
}