Cod sursa(job #2661306)

Utilizator bogdi1bogdan bancuta bogdi1 Data 21 octombrie 2020 19:10:50
Problema Obiective Scor 100
Compilator cpp-32 Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <cstdio>
#include <algorithm>
#include <deque>
#include <vector>
#include <map>
#include <cstring>
using namespace std;
deque<int> st;
vector<int> g[32005];
vector<int> gg[32005];
int tata[20][32005];
int stramos[20][32005];
map< pair<int,int>, bool> emuchie;
struct Nod
{
    int disc,low;
} v[32005];
int sol[32005];
int viz[32005];
bool indeq[32005];
int nr,k;
void dfs(int nod)
{
    v[nod].disc=v[nod].low=++nr;
    st.push_back(nod);
    for(int i=0; i<g[nod].size(); i++){
        if(v[g[nod][i]].disc==0){
            dfs(g[nod][i]);
            v[nod].low=min(v[nod].low, v[g[nod][i]].low);
        }
        else
            if(v[g[nod][i]].disc>0)
                v[nod].low=min(v[nod].low, v[g[nod][i]].disc);
    }
    if(v[nod].low==v[nod].disc){
        ++k;
        while(st.back()!=nod){
            sol[st.back()]=k;
            v[st.back()].disc*=-1;
            st.pop_back();
        }
        sol[nod]=k;
        v[nod].disc*=-1;
        st.pop_back();
    }
}
void dfs2(int nod, int lvl)
{
    viz[nod]=lvl;
    for(int i=0; i<gg[nod].size(); i++)
        if(viz[gg[nod][i]]==0){
            stramos[0][gg[nod][i]]=nod;
            dfs2(gg[nod][i], lvl+1);
            tata[0][nod]=min(tata[0][nod], tata[0][gg[nod][i]]);
        }
}
int sus(int nod, int val)
{
    for(int i=17; i>=0; i--)
        if((1<<i)<=val){
            val-=(1<<i);
            nod=stramos[i][nod];
        }
    return nod;
}
int lca(int x, int y)
{
    if(viz[x]<viz[y])
        swap(x, y);
    x=sus(x, viz[x]-viz[y]);
    if(x==y)
        return x;
    for(int i=17; i>=0; i--)
        if(stramos[i][x]!=stramos[i][y]){
            x=stramos[i][x];
            y=stramos[i][y];
        }
    x=stramos[0][x];
    return x;
}
int main()
{   freopen("obiective.in", "r", stdin);
    freopen("obiective.out", "w", stdout);
    int n,m,x,y,i,j,t,lc,ans;
    scanf("%d%d", &n, &m);
    for(i=1; i<=m; i++){
        scanf("%d%d", &x, &y);
        g[x].push_back(y);
    }
    for(i=1; i<=n; i++)
        if(v[i].disc==0)
            dfs(i);
    for(i=1; i<=n; i++)
        sol[i]=k-sol[i]+1;
    for(i=1; i<=k; i++)
        tata[0][i]=i;
    for(i=1; i<=n; i++)
        for(j=0; j<g[i].size(); j++)
            if(sol[i]!=sol[g[i][j]] && emuchie[make_pair(sol[i], sol[g[i][j]])]==0){
                emuchie[make_pair(sol[i], sol[g[i][j]])]=1;
                gg[sol[i]].push_back(sol[g[i][j]]);
                tata[0][sol[g[i][j]]]=min(tata[0][sol[g[i][j]]], sol[i]);
            }
    for(i=1; i<=k; i++)
        sort(gg[i].begin(), gg[i].end());
    memset(viz, 0, sizeof(viz));
    dfs2(1, 1);
    for(i=1; i<=17; i++)
        for(j=1; j<=k; j++)
            tata[i][j]=tata[i-1][tata[i-1][j]];
    for(i=1; i<=17; i++)
        for(j=1; j<=k; j++)
            stramos[i][j]=stramos[i-1][stramos[i-1][j]];
    scanf("%d", &t);
    for(i=1; i<=t; i++){
        scanf("%d%d", &x, &y);
        x=sol[x];
        y=sol[y];
        lc=lca(x, y);
        if(x==lc)
            printf("0\n");
        else{
            ans=1;
            for(j=17; j>=0; j--)
                if(tata[j][x]>lc){
                    ans+=(1<<j);
                    x=tata[j][x];
                }
            printf("%d\n", ans);
        }
    }
    return 0;
}