Cod sursa(job #1722961)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 29 iunie 2016 13:59:14
Problema Obiective Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 3.67 kb
#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;
}