Pagini recente » Cod sursa (job #1435557) | Cod sursa (job #1226842) | Cod sursa (job #2830285) | Cod sursa (job #1715845) | Cod sursa (job #995992)
Cod sursa(job #995992)
#include <cstring>
#include <fstream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
int N, M, TS;
vector<int> V[32002], P[32002], Q[32002];
set<int> W[32002];
int nodv[32002], minv[32002], where[32002], comps;
int T[32002], Tn[32002], in[32002], out[32002], timp;
int level[32002], lowest[32002];
int str[32002][16];
bool S[32002];
int ST[32002], STP[32002], K[32002];
class compare
{
public: inline bool operator () (const int& i1, const int& i2)
{
return K[i1] < K[i2];
}
};
inline bool is_str(int x, int y)
{
return in[x] <= in[y] && out[x] >= out[y];
}
void Tarjan(int x)
{
S[x] = true;
nodv[x] = ++nodv[0];
minv[x] = nodv[x];
ST[++ST[0]] = x;
for (vector<int>::iterator it = V[x].begin(); it != V[x].end(); ++it)
{
if (!S[*it]) Tarjan(*it);
if (where[*it] == 0) minv[x] = min(minv[x], minv[*it]);
}
if (nodv[x] == minv[x])
{
++comps;
while (ST[ST[0]] != x)
{
where[ST[ST[0]]] = comps;
--ST[0];
}
where[ST[ST[0]]] = comps;
--ST[0];
}
}
void sortT(int x)
{
S[x] = true;
for (set<int>::iterator it = W[x].begin(); it != W[x].end(); ++it)
if (!S[*it])
sortT(*it);
ST[++ST[0]] = x;
}
void Dfs(int x)
{
S[x] = true;
in[x] = ++timp;
if (x != ST[ST[0]])
lowest[x] = Tn[x];
for (vector<int>::iterator it = P[x].begin(); it != P[x].end(); ++it)
{
if (!S[*it])
{
Tn[*it] = x;
level[*it] = level[x] + 1;
Dfs(*it);
if (x != ST[ST[0]])
if (level[lowest[*it]] < level[lowest[x]])
lowest[x] = lowest[*it];
}
if (x != ST[ST[0]])
if (level[*it] < level[lowest[x]])
lowest[x] = *it;
}
out[x] = ++timp;
}
void goDfs(int x)
{
STP[++STP[0]] = x;
for (vector<int>::iterator it = Q[x].begin(); it != Q[x].end(); ++it)
{
T[*it] = x;
goDfs(*it);
}
--STP[0];
for (int i = 0; i <= 15; ++i)
{
if (STP[0] >= (1 << i)) str[x][i] = STP[STP[0] - (1 << i) + 1];
else str[x][i] = ST[ST[0]];
}
}
int main()
{
ifstream fin("obiective.in");
ofstream fout("obiective.out");
fin >> N >> M;
for (int i = 1, nod1, nod2; i <= M; ++i)
{
fin >> nod1 >> nod2;
V[nod1].push_back(nod2);
}
for (int i = 1; i <= N; ++i)
if (!S[i])
Tarjan(i);
for (int i = 1; i <= N; ++i)
for (vector<int>::iterator it = V[i].begin(); it != V[i].end(); ++it)
if (where[*it] != where[i])
W[where[i]].insert(where[*it]);
memset(S, 0, sizeof(S));
ST[0] = 0;
for (int i = 1; i <= comps; ++i)
if (!S[i])
sortT(i);
for (int i = ST[0]; i >= 1; --i)
K[ST[i]] = ST[0] - i + 1;
for (int i = 1; i <= comps; ++i)
{
for (set<int>::iterator it = W[i].begin(); it != W[i].end(); ++it)
{
P[i].push_back(*it);
P[*it].push_back(i);
}
sort(P[i].begin(), P[i].end(), compare());
}
memset(S, 0, sizeof(S));
Dfs(ST[ST[0]]);
for (int i = 1; i <= comps; ++i)
if (lowest[i] != 0)
Q[lowest[i]].push_back(i);
goDfs(ST[ST[0]]);
fin >> TS;
for (int i = 1, nod1, nod2; i <= TS; ++i)
{
fin >> nod1 >> nod2;
nod1 = where[nod1], nod2 = where[nod2];
if (is_str(nod1, nod2)) fout << 0 << '\n';
else
{
int nodnow = nod1, steps = 0;
for (int j = 15; j >= 0; --j)
if (!is_str(str[nodnow][j], nod2))
{
nodnow = str[nodnow][j];
steps += (1 << j);
}
nodnow = T[nodnow];
++steps;
fout << steps << '\n';
}
}
fin.close();
fout.close();
}