Cod sursa(job #3363248)

Utilizator Radu_BicliBiclineru Radu Radu_Bicli Data 14 august 2026 15:38:31
Problema Obiective Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <bits/stdc++.h>

using namespace std;

#define USE_STD_IO 0
#if USE_STD_IO
	#define fin cin
	#define fout cout
#else
	ifstream fin("obiective.in");
	ofstream fout("obiective.out");
#endif

const int MAXLOG = 20;
int n, q, m, i, trick[64002];
vector<int> gr[2][64002];
vector<int> grNou[64002];

stack<int> st;

int idxComp, comp[64002];
set<pair<int, int>> mch;

int tata[MAXLOG][64002];
int jmp[MAXLOG][64002];
int niv[64002];

static inline void DFS1(const int nod) {
	comp[nod] = 1;
	for(const int vec : gr[0][nod]) {
		if(0 == comp[vec]) DFS1(vec);
	}
	st.push(nod);
}

static inline void DFS2(const int nod) {
	comp[nod] = idxComp;
	for(const int vec : gr[1][nod]) {
		if(0 == comp[vec]) DFS2(vec);
	}
}

static inline void CompTareConex(const int n) {
	for(int i = 1; i <= n; i++) {
		if(0 == comp[i]) DFS1(i);
	}
	memset(comp + 1, 0, n * sizeof(int));
	while(!st.empty()) {
		if(0 == comp[st.top()]) {
			idxComp++;
			DFS2(st.top());
		}
		st.pop();
	}
}

static inline void DFS3(const int nod) {
	for(const int vec : grNou[nod]) {
		if(0 == niv[vec]) {
			tata[0][vec] = nod;
			jmp[0][vec] = nod;
			niv[vec] = 1 + niv[nod];
			DFS3(vec);
		}
		else jmp[0][vec] = min(jmp[0][vec], nod);
	}
}

static inline void MakeArb(int n) {
	for(int i = 1; i <= n; i++) {
		for(int vec : gr[0][i]) {
			if(comp[i] != comp[vec]) {
				grNou[comp[i]].push_back(comp[vec]);
			}
		}
	}

	for(i = 1; i <= idxComp; i++) {
		sort(grNou[i].begin(), grNou[i].end());
	}
}

static inline void PrepJump(const int n) {
	for(i = n; 0 < i; i--) {
		jmp[0][tata[0][i]] = min(jmp[0][tata[0][i]], jmp[0][i]);
	}

	for(int j, i = 1; MAXLOG > i; i++) {
		for(j = 1; j <= n; j++) {
			tata[i][j] = tata[i - 1][tata[i - 1][j]];
			jmp[i][j] = jmp[i - 1][jmp[i - 1][j]];
		}
	}
}

static inline int LCA(int x, int y) {
	if(niv[x] < niv[y]) swap(x, y);

	int dif = niv[x] - niv[y];

	for(int i = 0; MAXLOG > i; i++) {
		if(dif >> i & 1) x = tata[i][x];
	}

	if(x == y) return x;

	for(i = MAXLOG - 1; 0 <= i; i--) {
		if(tata[i][x] != tata[i][y]) {
			x = tata[i][x];
			y = tata[i][y];
		}
	}
	return tata[0][x];
}

static inline int Numara(int nod, int lca) {
	if(nod == lca) return 0;

	int i, rasp = 1;
	for(i = MAXLOG; 0 <= i; i--) {
		if(niv[jmp[i][nod]] > niv[lca]) {
			rasp += (1 << i);
			nod = jmp[i][nod];
		}
	}
	return rasp;
}


int main() {
	#if USE_STD_IO
	ios_base::sync_with_stdio(false);
	#endif
	fin.tie(NULL);
	fout.tie(NULL);

	fin >> n >> m;
	for(i = 1; i <= m; i++) {
		int x, y;
		fin >> x >> y;
		gr[0][x].push_back(y);
		gr[1][y].push_back(x);
	}

	CompTareConex(n);
	MakeArb(n);

	niv[1] = 1;
	DFS3(1);
	PrepJump(idxComp);

	fin >> q;
	while(0 < q--) {
		int x, y;
		fin >> x >> y;
		x = comp[x];
		y = comp[y];
		fout << Numara(x, LCA(x, y)) << '\n';
	}

	return 0;
}