Cod sursa(job #389760)

Utilizator ciprianfFarcasanu Alexandru Ciprian ciprianf Data 2 februarie 2010 11:09:43
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <stdio.h>
#include <vector>
using namespace std;
#define NMAX 32010
#define FOR(i, v) for(vector<int>::iterator i = v.begin(); i != v.end(); ++i)
vector<int> G[NMAX], Gt[NMAX], V[NMAX];
bool viz[NMAX], w[NMAX];
int t[NMAX], T[NMAX], TT[NMAX], D[NMAX];
int R[NMAX][18];
int n, m;
int sursa;
void dfs(int x){
	viz[x] = true;
	FOR(i, G[x])
		if(!viz[*i])
			dfs(*i);
	t[++t[0]] = x;
}
void dfs2(int x){
	viz[x] = true;
	T[x] = T[0];
	FOR(i, Gt[x])
		if(!viz[*i])
			dfs2(*i);
}
void compactare(){
	dfs(1);
	memset(viz, 0, sizeof(viz));
	for(int i = n; i; --i)
		if(!viz[t[i]]){
			T[0]++;
			dfs2(t[i]);
		}
	for(int i = 1; i <= n; ++i)
		FOR(it, G[i])
			if(T[i] != T[*it]){
				//V[T[i]].push_back(T[*i]);
				//w[T[*i]] = true;
				R[T[*it]][0] = T[i];
			}
}
void RMQ(){
	int i,j,log;
	for(log = 0; (1<<log) <= T[0]; log++); log--;
	/*for(j = 1; j <= log; ++j)
		for(i = 1; i <= T[0]; ++i)
			R[i][j] = -1;*/
	//R[sursa][0] = -1;
	for(j = 1; j <= log; ++j)
		for(i = 1; i <= T[0]; ++i)
			if(R[i][j-1])
				R[i][j] = R[R[i][j-1]][j-1];
}
void dfs3(int x){
	if(R[x][0] == 0 || viz[x])
		return;
	viz[x] = true;
	dfs3(R[x][0]);
	D[x] = D[R[x][0]] + 1;
}
int lca(int x,int y){
	if(x == y) return 0;
	int s = 0, p = 1;
	if(D[x] < D[y]){
		swap(x, y);
		p = 0;
	}
	
	int log;
	for(log = 0; (1<<log) <= D[x]; ++log); log--;
	for(int i = log; i >= 0 ; --i)
		if(R[x][i] && D[R[x][i]] >= D[y]) {
			x = R[x][i];
			s += (1<<i)*p;
		}
	if(x == y) return s;
	for(int i = log; i >= 0; --i)
		if(R[x][i] && R[x][i] != R[y][i]){
			x = R[x][i];
			y = R[y][i];
			s += (1<<i);
		}
	return s+1;
}
	
void lowcom(){
	memset(viz, 0, sizeof(viz));
	for(int i = 1; i <= T[0]; ++i)
		if(!viz[i]) 
			dfs3(i);
	RMQ();
}
int main(){
	freopen("obiective.in", "r", stdin);
	freopen("obiective.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; ++i){
		int x, y;
		scanf("%d%d", &x, &y);
		G[x].push_back(y);
		Gt[y].push_back(x);
	}
	compactare();
	lowcom();
	int k;
	scanf("%d",&k);
	for(;k; --k){
		int x, y;
		scanf("%d%d", &x, &y);
		printf("%d\n",lca(T[x],T[y]));
	}
	return 0;
}