Cod sursa(job #592263)

Utilizator tiganu_dolarMancea Catalin tiganu_dolar Data 27 mai 2011 14:59:56
Problema Obiective Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 3.68 kb
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;

#define pb push_back
#define NMAX 33005
#define LMAX 21

int n,m,tsf[NMAX],c[NMAX],nrc,nr,st[NMAX];
char viz[NMAX];
vector<int> v[NMAX],vt[NMAX];
vector<int> vnou[NMAX],vnt[NMAX];
int h[NMAX],low[NMAX],L,k;
int d[NMAX][LMAX],rmq[NMAX][LMAX];

int find(int nod,int val,int put)
{
    if(!val)
        return nod;
    if((1<<put)>val)
        return find(nod,val,put-1);
    return find(d[nod][put],val-(1<<put),put-1);
}

int lca(int nod1,int nod2)
{
    int i;
    if(h[nod1]>h[nod2])
        nod1=find(nod1,h[nod1]-h[nod2],L);
    else if(h[nod1]<h[nod2])
        nod2=find(nod2,h[nod2]-h[nod1],L);
    for(i=L;i>=0;i--)
        if(d[nod1][i]!=d[nod2][i])
        {
            nod1=d[nod1][i];
            nod2=d[nod2][i];
        }
    if(nod1==nod2)
        return nod1;
    return d[nod1][0];
}

void dfs1(int nod)
{
	int i,vec,lim=v[nod].size();
	viz[nod]=1;
	for(i=0;i<lim;i++)
		if(!viz[vec=v[nod][i]])
			dfs1(vec);
	tsf[++nr]=nod;			
}

void dfs2(int nod,int comp)
{
	int i,vec,lim=vt[nod].size();
	viz[nod]=1;
	c[nod]=comp;
	for(i=0;i<lim;i++)
		if(!viz[vec=vt[nod][i]])
			dfs2(vec,comp);
}

void dfs3(int nod)
{
	int i,vec,lim=vnou[nod].size();
	viz[nod]=1;
	for(i=0;i<lim;i++)
		if(!viz[vec=vnou[nod][i]])
			dfs3(vec);
	st[nod]=++nr;	
}

void dfs4(int nod)
{
	int i,vec,lim=vnou[nod].size();
	viz[nod]=1;
	for(i=1;i<=L;i++)
		d[nod][i]=d[d[nod][i-1]][i-1];
	for(i=0;i<lim;i++)
		if(!viz[vec=vnou[nod][i]])
		{
			vnt[nod].pb(vec);
			d[vec][0]=nod;
			dfs4(vec);
		}	
		else
			vnt[vec].pb(nod);
}

void dfs5(int nod)
{
	int i,vec,lim=vnt[nod].size();
	viz[nod]=1;
	for(i=0;i<lim;i++)
		if(!viz[vec=vnt[nod][i]])
		{
			h[vec]=h[nod]+1;
			low[vec]=nod;
			dfs5(vec);
			if(h[low[nod]]>h[low[vec]])
				low[nod]=low[vec];
		}
		else if(h[low[nod]]>h[vec])
			low[nod]=vec;
}

inline int cmp(const int& a,const int& b)
{
	return st[a]>st[b];
}

void det(int poz)
{
	if(viz[poz])
		return ;
	int i;	
	det(low[poz]);
	for(i=1;(1<<i)<=nrc;i++)
		rmq[poz][i]=rmq[rmq[poz][i-1]][i-1];	
	viz[poz]=1;
}

int main()
{
	int i,j,a,b,lim,vec,r,l,sol;
	
	freopen("obiective.in","r",stdin);
	freopen("obiective.out","w",stdout);
	
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&a,&b);
		v[a].pb(b);
		vt[b].pb(a);
	}
	nr=0;
	for(i=1;i<=n;i++)
		if(!viz[i])
			dfs1(i);
	memset(viz,0,sizeof(viz));		
	for(i=n;i>=1;i--)	
		if(!viz[tsf[i]])
			dfs2(tsf[i],++nrc);
		
/*	for(i=1;i<=n;i++)
		printf("%d\n",c[i]);
*/
		
	for(i=1;i<=n;i++)
	{
		lim=v[i].size();
		for(j=0;j<lim;j++)
		{
			vec=v[i][j];		
			if(c[i]!=c[vec])
				vnou[c[i]].pb(c[vec]);
		}
	}
	
	memset(viz,0,sizeof(viz));
	nr=0;
	for(i=1;i<=nrc;i++)
		if(!viz[i])	
			dfs3(i);
	for(i=1;i<=nrc;i++)
		if(vnou[i].size())
			sort(vnou[i].begin(),vnou[i].end(),cmp);
			
/*	for(i=1;i<=nrc;i++)		
	{
		printf("Pentru %d: ",i);
		for(j=0;j<(int)vnou[i].size();j++)
			printf("%d ",vnou[i][j]);
		printf("\n");
	}
*/	
	memset(viz,0,sizeof(viz));
	for(i=1;i<=nrc;i++)		
	{
		for(j=0;j<(int)vnou[i].size();j++)
			viz[vnou[i][j]]=1;
	}
				
	memset(viz,0,sizeof(viz));
	
	for(L=0;(1<<L)<=nrc;L++);
	L--;		
	for(i=1;i<=nrc;i++)
		if(!viz[i])	
		{
			dfs4(i);
			memset(viz,0,sizeof(viz));
			dfs5(i);
			r=i;
			break;
		}
			
/*	for(i=1;i<=nrc;i++)
		printf("%d %d\n",i,low[i]);
*/	
	for(i=1;i<=nrc;i++)
		rmq[i][0]=low[i];
	memset(viz,0,sizeof(viz));
	viz[0]=1;
	for(i=1;i<=nrc;i++)
		if(!viz[i])
			det(i);
			
	scanf("%d",&k);
	for(i=1;i<=k;i++)
	{
		scanf("%d%d",&a,&b);
		a=c[a];b=c[b];
		l=lca(a,b);
		if(l==a)
		{
			printf("0\n");
			continue;
		}	
		sol=1;
		for(j=L;j>=0;j--)
			if(h[rmq[a][j]]>h[l])
			{
				a=rmq[a][j];			
				sol+=(1<<j);
			}		
		printf("%d\n",sol);	
	}			
	return 0;
}