Cod sursa(job #2975916)

Utilizator andu2006Alexandru Gheorghies andu2006 Data 7 februarie 2023 20:52:55
Problema Obiective Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <bits/stdc++.h>

using namespace std;
typedef int ll;
typedef pair<ll,ll> pll;
const int NMAX=1<<15,LGMAX=15,buffsize=1<<22;
ofstream fout("obiective.out");
FILE* fin;
char buff[buffsize];
int buffpos=-1;
int read(){
    int n=0;
    ++buffpos;
    while(buff[buffpos]>='0' && buff[buffpos]<='9'){
        n=(n<<1)+(n<<3)+(buff[buffpos]^48);
        ++buffpos;
    }
    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[NMAX][LGMAX],p[NMAX][LGMAX];
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[it][0]]<depth[Link[u][0]])
            Link[u][0]=Link[it][0];
    }
}
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[u][bit];
    if(u==v) return u;
    for(ll bit=LGMAX-1;bit>=0;bit--)
        if(p[u][bit]!=p[v][bit])
            u=p[u][bit],v=p[v][bit];
    return p[u][0];
}
int main()
{
    fin=fopen("obiective.in","r");
    fread(buff,1,buffsize,fin);
    ios_base::sync_with_stdio(false);
    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[i][0]=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[it][0]=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[i][0]])
                Link[i][0]=it;
        }
    }
    dfs2(root);
    for(ll bit=1;bit<LGMAX;bit++)
        for(ll i=1;i<=cntctc;i++)
            Link[i][bit]=Link[Link[i][bit-1]][bit-1],p[i][bit]=p[p[i][bit-1]][bit-1];
    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[u][bit]]>depth[w])
                    u=Link[u][bit],ans+=(1<<bit);
            }
            fout<<ans+1<<'\n';
        }
        else fout<<"0\n";
    }
    return 0;
}