Pagini recente » Cod sursa (job #2811053) | Cod sursa (job #2452045) | Cod sursa (job #2029087) | Cod sursa (job #1461650) | Cod sursa (job #2009649)
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int NMAX = 32005;
vector <int> graph[NMAX];
vector <int> graph_inv[NMAX];
int _stack[NMAX];
int _stack_size;
bool vis[NMAX];
void dfs_inv (int node) {
vis[node] = true;
for (auto it: graph_inv[node])
if (!vis[it])
dfs_inv(it);
_stack[++ _stack_size] = node;
}
int which_scc[NMAX];
void dfs (int node, int scc) {
vis[node] = true;
which_scc[node] = scc;
for (auto it: graph[node])
if (!vis[it])
dfs(it, scc);
}
vector <int> new_graph[NMAX];
vector <int> tree_graph[NMAX];
int degs[NMAX];
int h[NMAX];
int fathers[15][NMAX];
void dfs_lca (int node) {
h[node] = h[fathers[0][node]] + 1;
for (int i = 1; i < 15; ++ i)
fathers[i][node] = fathers[i - 1][fathers[i - 1][node]];
for (auto it: tree_graph[node]) {
fathers[0][it] = node;
dfs_lca(it);
}
}
int lca (int a, int b) {
if (h[a] > h[b])
swap(a, b);
for (int i = 14; i >= 0; -- i)
if (h[fathers[i][b]] >= h[a])
b = fathers[i][b];
if (a == b)
return a;
for (int i = 14; i >= 0; -- i)
if (fathers[i][a] != fathers[i][b]) {
a = fathers[i][a];
b = fathers[i][b];
}
return fathers[0][a];
}
int sus[15][NMAX];
void dfs_sus0 (int node) {
for (auto it: tree_graph[node]) {
dfs_sus0(it);
if (h[sus[0][it]] < h[sus[0][node]])
sus[0][node] = sus[0][it];
}
}
void dfs_sus (int node) {
for (int i = 1; i < 15; ++ i)
sus[i][node] = sus[i - 1][sus[i - 1][node]];
for (auto it: tree_graph[node])
dfs_sus(it);
}
int query (int a, int l) {
int ans = 0;
if (a == l)
return 0;
for (int i = 14; i >= 0; -- i)
if (h[sus[i][a]] > h[l]) {
a = sus[i][a];
ans += (1 << i);
}
return 1 + ans;
}
int main()
{
ifstream cin("obiective.in");
ofstream cout("obiective.out");
int n = 0, m = 0;
cin >> n >> m;
int a, b;
while (m --) {
cin >> a >> b;
graph[a].push_back(b);
graph_inv[b].push_back(a);
}
for (int i = 1; i <= n; ++ i)
if (!vis[i])
dfs_inv(i);
memset(vis, 0, sizeof(vis));
int sccs = 0;
for (int i = n; i; -- i)
if (!vis[_stack[i]])
dfs(_stack[i], ++ sccs);
for (int i = 1; i <= n; ++ i)
for (auto it: graph[i])
if (which_scc[i] != which_scc[it])
new_graph[which_scc[i]].push_back(which_scc[it]);
n = sccs;
//Deschiderea tranzitiva
for (int i = 1; i <= n; ++ i)
for (auto it: new_graph[i]) {
if (!degs[it]) {
++ degs[it];
tree_graph[i].push_back(it);
}
}
dfs_lca(n);
//Calculam sus-urilie
for (int i = 1; i <= n; ++ i)
sus[0][i] = i;
for (int i = 1; i <= n; ++ i)
for (auto it: new_graph[i])
if (h[i] < h[sus[0][it]])
sus[0][it] = i;
dfs_sus0(n);
dfs_sus(n);
//Raspundem la query-uri
int q = 0;
cin >> q;
int l;
while (q --) {
cin >> a >> b;
a = which_scc[a], b = which_scc[b];
l = lca(a, b);
cout << query(a, l) << '\n';
}
cin.close();
cout.close();
return 0;
}