Cod sursa(job #2975922)

Utilizator andu2006Alexandru Gheorghies andu2006 Data 7 februarie 2023 20:58:23
Problema Obiective Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3 kb
#include <bits/stdc++.h>
#pragma GCC optimize("unroll-loops")

using namespace std;
typedef int ll;
typedef pair<ll,ll> pll;
const int NMAX=1<<15,LGMAX=15;
ifstream fin("obiective.in");
ofstream fout("obiective.out");
ll low[NMAX],tin[NMAX],cid[NMAX],tid=0,cntctc=0;
bool visited[NMAX];
stack<ll> cnd;
vector<ll> edg[NMAX];
vector<ll> ctc_edg[NMAX],ctc_redg[NMAX];
ll indeg[NMAX],depth[NMAX];
ll Link[LGMAX][NMAX],p[LGMAX][NMAX];
void dfs(ll u){
    low[u]=tin[u]=++tid;
    cnd.push(u);
    visited[u]=1;
    for(auto it : edg[u]){
        if(tin[it]==0) dfs(it),low[u]=min(low[u],low[it]);
        else if(visited[it]) low[u]=min(low[u],tin[it]);
    }
    if(tin[u]==low[u]){
        ll x; cntctc++;
        do{
            x=cnd.top();
            cid[x]=cntctc;
            cnd.pop();
            visited[x]=0;
        }while(x!=u);
    }
}
void dfs2(ll u){
    for(auto it : ctc_edg[u]){
        dfs2(it);
        if(depth[Link[0][it]]<depth[Link[0][u]])
            Link[0][u]=Link[0][it];
    }
}
ll LCA(ll u, ll v){
    if(depth[u]<depth[v]) swap(u,v);
    for(ll bit=LGMAX-1;bit>=0;bit--)
        if(depth[u]-(1<<bit)>=depth[v])
            u=p[bit][u];
    if(u==v) return u;
    for(ll bit=LGMAX-1;bit>=0;bit--)
        if(p[bit][u]!=p[bit][v])
            u=p[bit][u],v=p[bit][v];
    return p[0][u];
}
int main()
{
    ios_base::sync_with_stdio(false);
    ll n,m;
    fin>>n>>m;
    for(ll i=0;i<m;i++){
        ll u,v;
        fin>>u>>v;
        edg[u].push_back(v);
    }
    for(ll i=1;i<=n;i++)
        if(tin[i]==0)
            dfs(i);
    for(ll i=1;i<=n;i++){
        for(auto it : edg[i]){
            if(cid[i]!=cid[it]){
                ctc_edg[cid[i]].push_back(cid[it]);
                ctc_redg[cid[it]].push_back(cid[i]);
                ++indeg[cid[it]];
            }
        }
    }
    for(ll i=1;i<=n;i++)
        Link[0][i]=i;
    for(ll i=1;i<=n;i++) edg[i].clear();
    queue<ll> q;
    ll root=0;
    for(ll i=1;i<=cntctc;i++)
        if(indeg[i]==0)
            q.push(i),depth[i]=0,ctc_redg[i].push_back(0),root=i;

    while(!q.empty()){
        for(auto it : ctc_edg[q.front()]){
            --indeg[it];
            if(indeg[it]==0){
                p[0][it]=q.front();
                depth[it]=depth[q.front()]+1;
                q.push(it);
            }
        }
        q.pop();
    }
    for(ll i=1;i<=cntctc;i++){
        for(auto it : ctc_redg[i]){
            if(depth[it]<depth[Link[0][i]])
                Link[0][i]=it;
        }
    }
    dfs2(root);
    for(ll bit=1;bit<LGMAX;bit++)
        for(ll i=1;i<=cntctc;i++)
            Link[bit][i]=Link[bit-1][Link[bit-1][i]],p[bit][i]=p[bit-1][p[bit-1][i]];
    ll queries; fin>>queries;
    while(queries--){
        ll u,v,ans=0;
        fin>>u>>v;
        u=cid[u],v=cid[v];
        ll w=LCA(u,v);
        if(u!=w){
            for(ll bit=LGMAX-1;bit>=0;bit--){
                if(depth[Link[bit][u]]>depth[w])
                    u=Link[bit][u],ans+=(1<<bit);
            }
            fout<<ans+1<<'\n';
        }
        else fout<<"0\n";
    }
    return 0;
}