Pagini recente » Cod sursa (job #1786298) | Cod sursa (job #3185735) | Cod sursa (job #374875) | Cod sursa (job #525953) | Cod sursa (job #1722959)
#include<cstdio>
#include<vector>
#include<algorithm>
#define MAXN 32010
#define MAXLOG 18
using namespace std;
vector<int> g[MAXN],gt[MAXN],dag[MAXN];
int n,m,components,pointer=0;
int seen[MAXN],DFSorder[MAXN],component[MAXN],order[MAXN],depth[MAXN];
int dad[MAXLOG][MAXN],low[MAXLOG][MAXN];
void FirstDFS(int node){
int i;
seen[node]=1;
for(i=0;i<g[node].size();i++)
if(seen[g[node][i]]==0)
FirstDFS(g[node][i]);
pointer++;
DFSorder[pointer]=node;
}
void SecondDFS(int node){
int i;
seen[node]=0;
component[node]=components;
for(i=0;i<gt[node].size();i++)
if(seen[gt[node][i]]==1)
SecondDFS(gt[node][i]);
}
void StronglyConnectedComponents(){
int i,j;
for(i=1;i<=n;i++)
if(seen[i]==0)
FirstDFS(i);
for(i=n;i>=1;i--)
if(seen[DFSorder[i]]==1){
components++;
SecondDFS(DFSorder[i]);
}
for(i=1;i<=n;i++)
for(j=0;j<g[i].size();j++)
if(component[i]!=component[g[i][j]])
dag[component[i]].push_back(component[g[i][j]]);
n=components;
}
void TopologicalSort(int node){
int i;
seen[node]=1;
for(i=0;i<dag[node].size();i++)
if(seen[dag[node][i]]==0)
TopologicalSort(dag[node][i]);
pointer++;
order[node]=pointer;
}
bool Compare(int a,int b){
return order[a]>order[b];
}
void DFS(int node,int father){
int i;
seen[node]=0;
depth[node]=depth[father]+1;
dad[0][node]=father;
low[0][node]=father;
for(i=0;i<dag[node].size();i++)
if(seen[dag[node][i]]==1)
DFS(dag[node][i],node);
else
if(depth[node]<depth[low[0][dag[node][i]]])
low[0][dag[node][i]]=node;
}
void ComputeLowest(int node){
int i;
seen[node]=1;
for(i=0;i<dag[node].size();i++)
if(seen[dag[node][i]]==0){
ComputeLowest(dag[node][i]);
if(depth[low[0][node]]>depth[low[0][dag[node][i]]])
low[0][node]=low[0][dag[node][i]];
}
}
void Ancestors(){
int i,j;
for(i=1;(1<<i)<=n;i++)
for(j=1;j<=n;j++){
dad[i][j]=dad[i-1][dad[i-1][j]];
low[i][j]=low[i-1][low[i-1][j]];
}
}
int LCA(int x,int y){
int temp,i,difference;
if(depth[x]<depth[y]){
temp=x;
x=y;
y=temp;
}
difference=depth[x]-depth[y];
for(i=0;i<=17;i++)
if((difference&(1<<i)))
x=dad[i][x];
if(x==y)
return x;
for(i=17;i>=0;i--)
if(dad[i][x]>0&&dad[i][x]!=dad[i][y]){
x=dad[i][x];
y=dad[i][y];
}
return dad[0][x];
}
int main(){
freopen("obiective.in","r",stdin);
freopen("obiective.out","w",stdout);
int i,a,b,c,queries,query,answer;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%d%d",&a,&b);
g[a].push_back(b);
gt[b].push_back(a);
}
StronglyConnectedComponents();
pointer=0;
TopologicalSort(1);
for(i=1;i<=n;i++)
sort(dag[i].begin(),dag[i].end(),Compare);
DFS(1,0);
ComputeLowest(1);
Ancestors();
scanf("%d",&queries);
for(query=1;query<=queries;query++){
scanf("%d%d",&a,&b);
a=component[a];
b=component[b];
c=LCA(a,b);
if(a==b||a==c){
printf("0\n");
continue;
}
answer=1;
for(i=17;i>=0;i--)
if(depth[low[i][a]]>depth[c]){
a=low[i][a];
answer=answer+(1<<i);
}
printf("%d\n",answer);
}
return 0;
}