Cod sursa(job #3345570)

Utilizator Andrei-Dani-10Pisla Andrei Daniel Andrei-Dani-10 Data 10 martie 2026 09:29:59
Problema Obiective Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.51 kb
#include <fstream>

#include <vector>
#include <deque>

#include <utility>
#define x first
#define y second

using namespace std;

ifstream in("obiective.in");
ofstream out("obiective.out");

typedef pair <int, int> pii;
const int nmax = 32000, qmax = 1e5, maxint = (1 << 30);
int n, m, nrq, xx, yy;

vector <int> edges[nmax + 2];
vector <int> revedges[nmax + 2];

vector <int> edgescomp[nmax + 2];
vector <int> revedgescomp[nmax + 2];

int dpswaps[nmax + 2];
int answer[qmax + 2];

int lastt[nmax + 2];
int arrynodes[nmax + 2];

/// ---> get strongly conected components <--- ///
int strongcomponent[nmax + 2];
int visited[nmax + 2];
int toposort[nmax + 2];

int nodescc[nmax + 2];

void dfscomputetopo(int node){
    visited[node] = 1;
    for(auto nxt : edges[node]){
        if(!visited[nxt]) dfscomputetopo(nxt);
    }
    toposort[++toposort[0]] = node;

    return;
}

void dfsmarkcomponents(int node){
    strongcomponent[node] = strongcomponent[0];
    nodescc[++nodescc[0]] = node;

    for(auto nxt : revedges[node]){
        if(!strongcomponent[nxt])
            dfsmarkcomponents(nxt);
    }
    return;
}

/// ---> queries in O(n * q) <--- ///
vector <pii> queries[nmax + 2];

void solvestronglycomponent(int xx){
    for(int i = 1; i <= strongcomponent[0]; i++){
        dpswaps[i] = maxint;
    }

    deque <int> dq;
    dpswaps[xx] = 0;
    dq.push_front(xx);

    for(int node; !dq.empty(); ){
        node = dq.front(); dq.pop_front();

        for(auto nxt : edgescomp[node]){
            if(dpswaps[nxt] > dpswaps[node])
                dpswaps[nxt] = dpswaps[node], dq.push_front(nxt);
        }

        for(auto nxt : revedgescomp[node]){
            if(dpswaps[nxt] > dpswaps[node] + 1)
                dpswaps[nxt] = dpswaps[node] + 1, dq.push_back(nxt);
        }
    }

    for(auto qry : queries[xx]){
        answer[qry.y] = dpswaps[qry.x];
    }

    return;
}

int main(){

    in>>n>>m;
    for(int i = 1; i <= m; i++){
        in>>xx>>yy;
        edges[xx].push_back(yy);
        revedges[yy].push_back(xx);
    }

    /// ---> compute strongly conected components <--- ///
    for(int i = 1; i <= n; i++){
        if(!visited[i]) dfscomputetopo(i);
    }

    for(int i = n; i >= 1; i--){
        if(!strongcomponent[toposort[i]]){
            strongcomponent[0]++;
            dfsmarkcomponents(toposort[i]);
        }
    }

    /// ---> now we have a much simpler graph <--- ///

    for(int i = 1, node; i <= n; i++){
        node = nodescc[i]; lastt[0] = strongcomponent[node];
        arrynodes[++arrynodes[0]] = node;

        lastt[strongcomponent[node]] = lastt[0];

        for(auto nxt : edges[i]){
            if(lastt[strongcomponent[nxt]] == lastt[0]){ continue; }

            edgescomp[strongcomponent[node]].push_back(strongcomponent[nxt]);
            lastt[strongcomponent[nxt]] = lastt[0];
        }

        if(1 || i == n || strongcomponent[node] != strongcomponent[nodescc[i + 1]]){

            for(int j = 1; j <= arrynodes[0]; j++){
                node = arrynodes[j];

                for(auto nxt : revedges[node]){
                    if(lastt[strongcomponent[nxt]] == lastt[0]){ continue; }

                    revedgescomp[strongcomponent[node]].push_back(strongcomponent[nxt]);
                    lastt[strongcomponent[nxt]] = lastt[0];
                }
            }

            arrynodes[0] = 0;
        }
    }

    /**for(int i = 1; i <= n; i++){
        lastt[0]++; ///simplfy graph :D

        for(auto nxt : edges[i]){
            if(strongcomponent[i] == strongcomponent[nxt]){ continue; }
            edgescomp[strongcomponent[i]].push_back(strongcomponent[nxt]);

            lastt[strongcomponent[nxt]] = lastt[0];
        }

        for(auto nxt : revedges[i]){
            if(strongcomponent[i] == strongcomponent[nxt]){ continue; }
            if(lastt[strongcomponent[nxt]] == lastt[0]){ continue; }

            revedgescomp[strongcomponent[i]].push_back(strongcomponent[nxt]);
        }
    }**/

    /// ---> answer queries <--- ///

    in>>nrq;
    for(int itq = 1; itq <= nrq; itq++){
        in>>xx>>yy;

        queries[strongcomponent[xx]].push_back(make_pair(strongcomponent[yy], itq));
    }

    for(int comp = 1; comp <= strongcomponent[0]; comp++){
        if(!queries[comp].size()){ continue; }

        solvestronglycomponent(comp);
    }

    for(int itq = 1; itq <= nrq; itq++){
        out<<answer[itq]<<"\n";
    }

    return 0;
}