Pagini recente » Cod sursa (job #112521) | Cod sursa (job #1709892) | Cod sursa (job #1170659) | Cod sursa (job #1830684) | Cod sursa (job #2983631)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("obiective.in");
ofstream fout("obiective.out");
const int nmax = 32000;
const int LOG = 15;
int n, m, t;
bool visited[nmax + 5];
vector<int> g[nmax + 5];
pair<int, int> muchii[nmax + 5];
stack<int> sortTop;
int pozSortTop[nmax + 5];
int cntSortTop;
int grad[nmax + 5];
int nivel[nmax + 5];
int idxCtc[nmax + 5];
int cntCtc;
int stramosi[nmax + 5][LOG + 1];
int in[nmax + 5], out[nmax + 5], timp;
void dfs1(int fiu)
{
visited[fiu] = true;
for(auto it : g[fiu])
{
if(visited[it] == true)
{
continue;
}
dfs1(it);
}
sortTop.push(fiu);
}
void dfs2(int fiu)
{
visited[fiu] = true;
idxCtc[fiu] = cntCtc;
for(auto it : g[fiu])
{
if(visited[it] == true)
{
continue;
}
dfs2(it);
}
}
bool bypoz(int a, int b)
{
return pozSortTop[a] < pozSortTop[b];
}
void dfs3(int fiu)
{
timp++;
in[fiu] = timp;
visited[fiu] = true;
for(int i = 1; i <= LOG; i ++)
{
stramosi[fiu][i] = stramosi[stramosi[fiu][i - 1]][i - 1];
}
for(auto it : g[fiu])
{
if(visited[it] == true)
{
continue;
}
nivel[it] = 1 + nivel[fiu];
stramosi[it][0] = fiu;
dfs3(it);
}
out[fiu] = timp;
}
bool eStramos(int x, int y)
{
return in[x] <= in[y] && out[x] >= out[y];
}
int Lca(int x, int y)
{
if(eStramos(x, y) == true)
{
return 0;
}
int ans = 1;
for(int i = LOG; i >= 0; i --)
{
if(eStramos(stramosi[x][i], y) == false && stramosi[x][i] != 0)
{
ans += (1 << i);
x = stramosi[x][i];
}
}
return ans;
}
int main()
{
fin >> n >> m;
for(int i = 1; i <= m; i ++)
{
int x, y;
fin >> x >> y;
muchii[i] = {x, y};
g[x].push_back(y);
}
for(int i = 1; i <= n; i ++)
{
if(!visited[i])
{
dfs1(i);
}
}
for(int i = 1; i <= n; i ++)
{
g[i].clear();
visited[i] = false;
}
for(int i = 1; i <= m; i ++)
{
g[muchii[i].second].push_back(muchii[i].first);
}
while(!sortTop.empty())
{
int nod = sortTop.top();
sortTop.pop();
if(!visited[nod])
{
cntCtc++;
dfs2(nod);
}
}
for(int i = 1; i <= n; i ++)
{
g[i].clear();
}
for(int i = 1; i <= m; i ++)
{
int x = idxCtc[muchii[i].first];
int y = idxCtc[muchii[i].second];
if(x != y)
{
g[x].push_back(y);
grad[y]++;
}
}
n = cntCtc;
int root = 0;
for(int i = 1; i <= n; i ++)
{
if(grad[i] == 0)
{
root = i;
}
}
queue<int> coada;
coada.push(root);
while(!coada.empty())
{
int nod = coada.front();
coada.pop();
cntSortTop++;
pozSortTop[nod] = cntSortTop;
for(auto it : g[nod])
{
grad[it]--;
if(grad[it] == 0)
{
coada.push(it);
}
}
}
for(int i = 1; i <= n; i ++)
{
visited[i] = false;
//sort(g[i].begin(), g[i].end(), bypoz);
}
nivel[root] = 1;
dfs3(root);
fin >> t;
while(t--)
{
int x, y;
fin >> x >> y;
x = idxCtc[x];
y = idxCtc[y];
if(x == y)
{
fout << 0 << '\n';
}
else
{
fout << Lca(x, y) << '\n';
}
}
/// ? :>:>:>
}