Cod sursa(job #2147902)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 1 martie 2018 10:57:54
Problema Obiective Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <deque>

using namespace std;

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

const int nmax = 32e3;
const int inf = 1 << 30;

int n, nrc;
bool viz[nmax + 1];
int comp[nmax + 1];
vector< int > ord, g[ 2 ][nmax + 1];

int d[nmax + 1];
bool gata[nmax + 1];
deque< int > q;
vector< pair<int, int> > gc[nmax + 1];

void dfs (int nod, int ind) {
    viz[ nod ] = 1;
    if (ind == 1)
        comp[ nod ] = nrc;

    for (auto i : g[ ind ][ nod ]) {
        if (viz[ i ] == 0) {
            dfs(i, ind);
        }
    }

    if (ind == 0)
        ord.push_back( nod );
}

void ctc () {
    for (int i = 1; i <= n; ++ i) {
        if (viz[ i ] == 0)
            dfs(i, 0);
    }

    memset(viz, 0, sizeof(viz));
    reverse(ord.begin(), ord.end());

    for (auto i : ord) {
        if (viz[ i ] == 0) {
            ++ nrc;
            dfs(i, 1);
        }
    }
}

int dijkstra (int x, int y) {
    for (int i = 1; i <= nrc; ++ i) {
        gata[ i ] = 0;
        d[ i ] = inf;
    }

    d[ x ] = 0;
    q.push_back( x );

    while (!q.empty()) {
        int w = q.front();
        q.pop_front();

        if (gata[ w ] == 1)
            continue;
        gata[ w ] = 1;

        for (auto i : gc[ w ]) {
            if (gata[ i.first ] == 0 && d[ i.first ] > d[ w ] + i.second) {
                d[ i.first ] = d[ w ] + i.second;

                if (i.second == 0)
                    q.push_front( i.first );
                else
                    q.push_back( i.first );
            }
        }
    }

    return d[ y ];
}

int main () {
    int m;
    fin >> n >> m;

    for (int i = 1; i <= m; ++ i) {
        int x, y;
        fin >> x >> y;
        g[ 0 ][ x ].push_back( y );
        g[ 1 ][ y ].push_back( x );
    }

    ctc ();

    for (int i = 1; i <= n; ++ i) {
        for (auto j : g[ 0 ][ i ]) {
            gc[ comp[ i ] ].push_back(make_pair(comp[ j ], 0));
            gc[ comp[ j ] ].push_back(make_pair(comp[ i ], 1));
        }
    }

    for (int i = 1; i <= nrc; ++ i) {
        sort(gc[ i ].begin(), gc[ i ].end());
        gc[ i ].erase(unique(gc[ i ].begin(), gc[ i ].end()), gc[ i ].end());
    }

    int t;
    fin >> t;

    while (t --) {
        int x, y;
        fin >> x >> y;

        x = comp[ x ], y = comp[ y ];
        fout << dijkstra(x, y) << "\n";
    }

    fin.close();
    fout.close();
    return 0;
}