Cod sursa(job #2975969)

Utilizator andu2006Alexandru Gheorghies andu2006 Data 7 februarie 2023 22:08:23
Problema Obiective Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.48 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,buffsize=1<<13;
ofstream fout("obiective.out");
FILE* fin;
char buff[buffsize];
int buffpos=buffsize;
int read(){
    if(buffpos==buffsize) fread(buff,1,buffsize,fin),buffpos=0;
    int n=0;
    while(buff[buffpos]<'0' || buff[buffpos]>'9'){
        ++buffpos;
        if(buffpos==buffsize) fread(buff,1,buffsize,fin),buffpos=0;
    }
    while(buff[buffpos]>='0' && buff[buffpos]<='9'){
        n=(n<<1)+(n<<3)+(buff[buffpos]^48);
        ++buffpos;
        if(buffpos==buffsize) fread(buff,1,buffsize,fin),buffpos=0;
    }
    return n;
}
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],ln[NMAX],rn[NMAX],eid;
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){
    ln[u]=1e6;
    for(auto it : ctc_edg[u]){
        dfs2(it);
        ln[u]=min(ln[u],ln[it]);
        if(depth[Link[0][it]]<depth[Link[0][u]])
            Link[0][u]=Link[0][it];
    }
    rn[u]=++eid;
    if(ln[u]==1e6) ln[u]=rn[u];
}
ll LCA(ll u, ll v){
    if(ln[u]<=ln[v] && rn[v]<=rn[u]) return u;
    for(ll bit=LGMAX-1;bit>=0;bit--){
        ll w=p[bit][u];
        if(ln[w]<=ln[v] && rn[v]<=rn[w]) u=w;
    }
    return p[0][u];
}
int main()
{
    ios_base::sync_with_stdio(false);
    fin=fopen("obiective.in","r");
    ll n=read(),m=read();
    for(ll i=0;i<m;i++){
        ll u=read(),v=read();
        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]=p[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,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=read();
    while(queries--){
        ll u=read(),v=read(),ans=0;
        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;
}