Pagini recente » Cod sursa (job #3173144) | Cod sursa (job #3264482) | Cod sursa (job #1605390) | Cod sursa (job #1707702) | Cod sursa (job #3225049)
#include <bits/stdc++.h>
#ifdef LOCAL
#define in cin
#define out cout
#endif
using namespace std;
#ifndef LOCAL
ifstream in("obiective.in");
ofstream out("obiective.out");
#endif
const int nmax = 32005;
const int lgmax = 17;
int col = 1;
int color[nmax];
struct ctc
{
vector<int> adj[nmax];
int ind = 1;
int depth[nmax], low[nmax];
int state[nmax];
stack<int> s;
void adde(int a, int b)
{
adj[a].push_back(b);
}
void dfs(int nod = 1)
{
depth[nod] = low[nod] = ind++;
s.push(nod);
state[nod] = 1;
for (auto i : adj[nod])
{
if (state[i] == 1)
{
low[nod] = min(low[nod], depth[i]);
}
else if (state[i] == 0)
{
dfs(i);
low[nod] = min(low[nod], low[i]);
}
}
if (low[nod] == depth[nod])
{
while (s.top() != nod)
{
color[s.top()] = col;
state[s.top()] = 2;
s.pop();
}
color[s.top()] = col;
state[s.top()] = 2;
s.pop();
col++;
}
}
} root1;
struct sorttop
{
vector<int> adj[nmax];
int enters[nmax];
vector<int> topp;
bool viz[nmax];
void adde(int a, int b)
{
adj[a].push_back(b);
enters[b]++;
}
void dfs(int nod)
{
viz[nod] = 1;
topp.push_back(nod);
for (auto i : adj[nod])
{
enters[i]--;
if (enters[i] == 0)
{
dfs(i);
}
}
}
void dosort()
{
for (int i = 1; i <= col; i++)
{
if (!viz[i] && enters[i] == 0)
{
dfs(i);
}
}
}
} root2;
vector<int> revadj[nmax];
vector<int> adj[nmax];
int depth[nmax];
bool viz[nmax];
int root;
int dp[nmax][lgmax];
struct LCA
{
int parent[nmax][lgmax];
void dfs(int nod, int p)
{
parent[nod][0] = p;
for (auto i = 1; i < lgmax; i++)
{
parent[nod][i] = parent[parent[nod][i - 1]][i - 1];
}
for (auto i : adj[nod])
{
dfs(i, nod);
}
}
int lca(int a, int b)
{
if (depth[a] < depth[b])
{
swap(a, b);
}
for (int i = lgmax - 1; i >= 0; i--)
{
if (depth[parent[a][i]] >= depth[b])
{
a = parent[a][i];
}
}
if (a == b)
{
return a;
}
for (int i = lgmax - 1; i >= 0; i--)
{
if (parent[a][i] != parent[b][i])
{
a = parent[a][i];
b = parent[b][i];
}
}
return parent[a][0];
}
} root3;
int bestnode(int a, int b)
{
if (depth[a] < depth[b])
{
return a;
}
return b;
}
void dfs(int nod, int lg)
{
dp[nod][lg] = nod;
for (auto i : adj[nod])
{
dfs(i, lg);
dp[nod][lg] = bestnode(dp[nod][lg], dp[i][lg]);
}
if (lg == 0)
{
for (auto i : revadj[nod])
{
dp[nod][0] = bestnode(dp[nod][0], i);
}
}
else
{
dp[nod][lg] = bestnode(dp[nod][lg], dp[dp[nod][lg - 1]][lg - 1]);
}
}
int bins(int nod, int d)
{
int ans = 0;
if (depth[nod] == d)
ans = -1;
for (int step = lgmax - 1; step >= 0; step--)
{
if (depth[dp[nod][step]] > d)
{
nod = dp[nod][step];
ans += (1 << step);
}
}
return ans + 1;
}
int main()
{
int n, m;
in >> n >> m;
vector<pair<int, int>> muchii;
for (int i = 0; i < m; i++)
{
int a, b;
in >> a >> b;
muchii.push_back({a, b});
root1.adde(a, b);
}
root1.dfs();
col--;
for (auto i : muchii)
{
if (color[i.first] != color[i.second])
{
root2.adde(color[i.first], color[i.second]);
revadj[color[i.second]].push_back(color[i.first]);
}
}
root2.dosort();
auto topp = root2.topp;
root = topp[0];
depth[root] = 1;
viz[root] = 1;
for (int i = 1; i < col; i++)
{
int maxx = 0;
int maxxind = 0;
for (auto j : revadj[topp[i]])
{
if (viz[j])
{
if (maxx < depth[j])
{
maxx = depth[j];
maxxind = j;
}
}
}
viz[topp[i]] = 1;
depth[topp[i]] = maxx + 1;
adj[maxxind].push_back(topp[i]);
}
root3.dfs(root, 0);
for (int i = 0; i < lgmax; i++)
{
dfs(root, i);
}
return 0;
int q;
in >> q;
for (int i = 0; i < q; i++)
{
int a, b;
in >> a >> b;
int c = root3.lca(color[a], color[b]);
out << bins(color[a], depth[c]) << '\n';
}
}