Pagini recente » Cod sursa (job #3139723) | Cod sursa (job #1416157) | Cod sursa (job #3196556) | Cod sursa (job #517052) | Cod sursa (job #2730478)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("obiective .in");
ofstream fout ("obiective.out");
bool viz[32002];
int n, m, x, y, nr, c[32002], grad[32002];
vector<int>v1[32002];
vector<int>v2[32002];
vector<int>ctc[32002];
stack<int>st;
void dfs (int x) {
viz[x] = 1;
for (int i = 0; i < v1[x].size(); i++) {
if (!viz[v1[x][i]])
dfs(v1[x][i]);
}
st.push(x);
}
void dfs2 (int x) {
viz[x] = 1;
for (int i = 0; i < v2[x].size(); i++) {
if (!viz[v2[x][i]])
dfs2(v2[x][i]);
}
c[x] = nr;
}
int dp[17][32002], lvl[32002], dp2[17][32002];
void dfslol (int x, int par) {
dp2[0][x] = par;
dp[0][x] = par;
lvl[x] = lvl[par] + 1;
viz[x] = 1;
for (auto it : ctc[x]) {
if (!viz[it]) {
dfslol(it, x);
}
else {
if (lvl[dp2[0][it]] > lvl[x])
dp2[0][it] = x;
}
}
}
void preamultdfs (int x, int par) {
viz[x] = 1;
for (auto it : ctc[x]) {
if (viz[it] == 0) {
preamultdfs(it, x);
if (lvl[dp2[0][x]] > lvl[dp2[0][it]])
dp2[0][x] = dp2[0][it];
}
}
}
set<pair<int, int> > s;
int lca (long long u, long long v) {
if (lvl[u] > lvl[v])
swap(u, v);
long long meh = lvl[v] - lvl[u];
for (long long i = 16; i >= 0; i--)
if (meh & (1 << i)) {
v = dp[i][v];
}
if (u == v) {
return v;
}
for (long long i = 16; i >= 0; i--) {
if (dp[i][u] != dp[i][v]) {
u = dp[i][u];
v = dp[i][v];
}
}
return dp[0][v];
}
int main()
{
fin >> n >> m;
for (int i = 1; i <= m; i++) {
fin >> x >> y;
v1[x].push_back(y);
v2[y].push_back(x);
}
for (int i = 1; i <= n; i++) {
if (viz[i] == 0)
dfs(i);
}
memset(viz, 0, sizeof(viz));
while (!st.empty()) {
if (viz[st.top()] == 0) {
nr++;
dfs2(st.top());
}
st.pop();
}
for (int i = 1; i <= n; i++)
for (auto it : v1[i])
if (c[it] != c[i] && s.find({c[i], c[it]}) == s.end()) {
s.insert({c[i], c[it]});
s.insert({c[it], c[i]});
ctc[c[i]].push_back({c[it]});
grad[c[it]]++;
}
for (int i = 1; i <= nr; i++) {
sort(ctc[i].begin(), ctc[i].end());
}
int root = 0;
for (int i = 1; i <= nr; i++)
if (grad[i] == 0)
root = i;
memset(viz, false, sizeof(viz));
dfslol(root, 0);
memset(viz, false, sizeof(viz));
preamultdfs(root, 0);
for (int i = 1; (1 << i) <= nr; i++)
for (int j = 1; j <= n; j++) {
dp[i][j] = dp[i - 1][dp[i - 1][j]];
dp2[i][j] = dp2[i - 1][dp2[i - 1][j]];
}
//cout << dp[1][c[11]] << " " << c[8] << "\n";
int t;
fin >> t;
while (t--) {
fin >> x >> y;
//cout << x << " " << y << "\n";
x = c[x];
y = c[y];
if (x == y) {
fout << "0\n";
continue;
}
else {
//cout << lvl[x] << " " << lvl[y] << "\n";
int l = lca(x, y);
if (x == l) {
fout << "0\n";
continue;
}
int ans = 0;
for (int i = 16; i >= 0; i--)
if (dp2[i][x] != 0 && lvl[dp2[i][x]] > lvl[l]) {
x = dp2[i][x];
ans += (1 << i);
}
fout << ans + 1 << "\n";
}
}
return 0;
}