Pagini recente » Cod sursa (job #1605840) | Cod sursa (job #198798) | Cod sursa (job #2064421) | Cod sursa (job #3040962) | Cod sursa (job #1266736)
#include <algorithm>
#include <fstream>
#include <stack>
#include <vector>
using namespace std;
#define N_SIZE 32001
ifstream is ("obiective.in");
ofstream os ("obiective.out");
int index[N_SIZE], L[N_SIZE], idx, comps, Gr[N_SIZE];
bool B[N_SIZE], b[N_SIZE];
stack <int> S;
vector <int> Gx[N_SIZE], C;
int Ap[N_SIZE], euler, RMQ[18][N_SIZE*2];
int N, M, T, root, Q;
vector <int> G[N_SIZE];
bool rev;
int x, y, lev, k, niva, nivb;
void TJ(int x);
void DFS(int x, int l);
void CreateTree();
void RangeMinimumQuery();
int QUERY(int a, int b);
int main()
{
is >> N >> M;
for (int i = 1, a, b; i <= M; ++i)
{
is >> a >> b;
Gx[a].push_back(b);
}
CreateTree();
DFS(root, 1);
RangeMinimumQuery();
is >> Q;
for (int i = 1, a, b; i <= Q; ++i)
{
is >> a >> b;
os << QUERY(Gr[a], Gr[b]) << '\n';
}
is.close();
os.close();
};
int QUERY(int a, int b)
{
rev = 0;
niva = RMQ[0][Ap[a]];
nivb = RMQ[0][Ap[b]];
x = Ap[a];
y = Ap[b];
if (x > y) swap(x, y), rev = 1;
k = 0;
for (int Z = 1; Z <= (y-x); Z*=2, ++k); --k;
lev = min(RMQ[k][y-(1<<k)+1], RMQ[k][x]);
return niva-lev;
};
void RangeMinimumQuery()
{
RMQ[0][euler] = 1;
for (int i = 1; (1<<i) <= euler; ++i)
for (int j = 1; j+(1<<i)-1 <= euler; ++j)
RMQ[i][j] = min(RMQ[i-1][j], RMQ[i-1][j+(1<<i-1)]);
};
void DFS(int x, int l)
{
b[x] = 1;
RMQ[0][++euler] = l;
Ap[x] = euler;
for (const auto& y : G[x])
{
DFS(y, l+1);
RMQ[0][++euler] = l;
}
};
void CreateTree()
{
for (int i = 1; i <= N; ++i)
if (index[i] == 0)
TJ(i);
for (int i = 1; i <= comps; ++i)
{
sort (G[i].begin(), G[i].end());
G[i].erase (unique(G[i].begin(), G[i].end()), G[i].end());
for (const auto& f : G[i])
b[f] = 1;
}
for (int i = 1; i <= comps; ++i)
if (b[i] == 0) { root = i; break; }
for (int i = 1; i <= comps; ++i)
b[i] = 0;
};
void TJ(int x)
{
B[x] = 1; S.push(x);
index[x] = L[x] = ++idx;
for (const auto& y : Gx[x])
if (index[y] == 0)
{
TJ(y);
L[x] = min(L[x], L[y]);
}
else if (B[y] == 1)
L[x] = min(L[x], L[y]);
if (index[x] == L[x])
{
++comps;
int y;
do {
y = S.top(); S.pop();
Gr[y] = comps;
C.push_back(y);
B[y] = 0;
} while (y != x);
for (const auto& node : C)
for (const auto& f : Gx[node])
if (Gr[node] != Gr[f] && Gr[f] != 0)
G[Gr[node]].push_back(Gr[f]);
C.clear();
}
};