Pagini recente » Cod sursa (job #3183400) | Clasament oni_10_2 | Cod sursa (job #935244) | Cod sursa (job #910717) | Cod sursa (job #1896819)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 32e3 + 69;
const int MAXLOG = 17;
const int INF = 2e9;
vector <int> g[MAXN + 1], gt[MAXN + 1];
set <int> dag[MAXN + 1];
stack <int> srt;
int anc[MAXLOG + 1][MAXN + 1], rmq[MAXLOG + 1][2 * MAXN + 1];
int comptc[MAXN + 1], prim[MAXN + 1], lg[2 * MAXN + 1];
bool seen[MAXN];
int comptc_num, euler_num;
void norm_dfs(int node) {
seen[node] = true;
for (auto it : g[node])
if (seen[it] == false)
norm_dfs(it);
srt.push(node);
}
void rev_dfs(int node) {
seen[node] = false;
comptc[node] = comptc_num;
for (auto it : gt[node])
if (seen[it])
rev_dfs(it);
}
void euler_traversal(int node) {
seen[node] = true;
prim[node] = ++euler_num;
rmq[0][euler_num] = node;
for (auto it : dag[node])
if (seen[it] == 0) {
euler_traversal(it);
rmq[0][++euler_num] = node;
anc[0][node] = min(anc[0][node], anc[0][it]);
}
}
int low_com_anc(int u, int v) {
if (prim[u] > prim[v])
swap(u, v);
int aux = lg[prim[v] - prim[u]];
return min(rmq[aux][prim[u]], rmq[aux][prim[v] - (1 << aux) + 1]);
}
int main()
{
int n, m, x, y, t, lca, ans;
for (int i = 2; i <= 2 * MAXN; ++i)
lg[i] = lg[i / 2] + 1;
ifstream fin("obiective.in");
fin >> n >> m;
for (int i = 0; i < m; ++i) {
fin >> x >> y;
g[x].push_back(y);
gt[y].push_back(x);
}
for (int i = 1; i <= n; ++i)
if (seen[i] == false)
norm_dfs(i);
while(srt.empty() == 0) {
if (seen[srt.top()]) {
++comptc_num;
rev_dfs(srt.top());
}
srt.pop();
}
for (int i = 1; i <= n; ++i)
anc[0][i] = INF;
for (int i = 1; i <= n; ++i) {
x = comptc[i];
for (auto it : g[i])
if (x != comptc[it]) {
y = comptc[it];
dag[x].insert(y);
anc[0][y] = min(anc[0][y], x);
}
}
euler_traversal(1);
for (int i = 1; i <= MAXLOG; ++i) {
for (int j = 1; j <= comptc_num; ++j)
anc[i][j] = anc[i - 1][anc[i - 1][j]];
for (int j = 1; j <= euler_num - (1 << i) + 1; ++j)
rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
}
fin >> t;
ofstream fout("obiective.out");
for (int i = 0; i < t; ++i) {
fin >> x >> y;
x = comptc[x]; y = comptc[y];
lca = low_com_anc(x, y);
ans = (x != lca);
for (int step = MAXLOG; step >= 0; --step)
if (anc[step][x] > lca) {
ans += (1 << step);
x = anc[step][x];
}
fout << ans << '\n';
}
fin.close();
fout.close();
return 0;
}