Cod sursa(job #2333721)

Utilizator Valentin0709Datcu George Valentin Valentin0709 Data 1 februarie 2019 21:12:33
Problema Obiective Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.7 kb
#include <stdio.h>
#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
using namespace std;

#define NMAX 32005
#define TMAX 100005
#define INF 2000000000

FILE * f = fopen("obiective.in", "r");
FILE * g = fopen("obiective.out", "w");

int n, m, t, x, y, u, indexx, ssize, nrctc, rez[TMAX], q[NMAX], ctc[NMAX], viz[NMAX], cost[NMAX], s[NMAX], idx[NMAX], lowlink[NMAX], onstack[NMAX];

vector<int> l[NMAX], l2[NMAX], ls[NMAX], ls2[NMAX], sol[NMAX];

struct locatie{
    int x, y, ind;
} loc[TMAX];

int comp(locatie a, locatie b) {
    return ctc[a.x] < ctc[b.x];
}

void citire_graf() {
    int x, y;

    fscanf(f, "%d%d", &n, &m);
    for(int i = 1; i <= m; i++) {
        fscanf(f, "%d%d", &x, &y);
        l[x].push_back(y);
        l2[y].push_back(x);
    }
}

void tarjan(int v) {
    int x;

    s[++ssize] = v; onstack[v] = 1;
    idx[v] = lowlink[v] = ++indexx;

    for(int i = 0; i < l[v].size(); i++) {
        int u = l[v][i];
        if(!idx[u]) {
            tarjan(u);
            lowlink[v] = min(lowlink[v], lowlink[u]);
        }
        else if(onstack[u]) lowlink[v] = min(lowlink[v], lowlink[u]);
    }

    if(idx[v] == lowlink[v]) {
        nrctc++;
        do {
            x = s[ssize];
            sol[nrctc].push_back(x);
            ctc[x] = nrctc;
            onstack[x] = 0; ssize--;
        } while(x != v);
    }
}

void drum_ctc(int i, int j) {
    for(int p = 0; p < sol[i].size(); p++) {
        int v = sol[i][p];
        for(int k = 0; k < l[v].size(); k++) {
            int u = l[v][k];
            if(ctc[u] == j) {
                ls[i].push_back(j);
                ls2[j].push_back(i);
                return;
            }
        }
        for(int k = 0; k < l2[v].size(); k++) {
            int u = l2[v][k];
            if(ctc[u] == j) {
                ls2[i].push_back(j);
                ls[j].push_back(i);
                return;
            }
        }
    }
}

void simplifica_graf() {
    for(int i = 1; i < nrctc; i++)
        for(int j = i + 1; j <= nrctc; j++) drum_ctc(i, j);
}

void bf(int x) {
    int q[NMAX], qsize = 0;

    for(int i = 1; i <= nrctc; i++) {
        viz[i] = 0; cost[i] = INF;
    }

    q[++qsize] = x; cost[x] = 0; viz[x] = 1;
    while(qsize) {
        int v = q[qsize--];
        viz[v] = 0;
        for(int i = 0; i < ls[v].size(); i++) {
            int u = ls[v][i];
            if(cost[u] > cost[v]) {
                cost[u] = cost[v];
                if(!viz[u]) {q[++qsize] = u; viz[u] = 1;}
            }
        }
        for(int i = 0; i < ls2[v].size(); i++) {
            int u = ls2[v][i];
            if(cost[u] > cost[v] + 1) {
                cost[u] = cost[v] + 1;
                if(!viz[u]) {q[++qsize] = u; viz[u] = 1;}
            }
        }
    }
}

int main() {

    citire_graf();

    for(int i = 1; i <= n; i++)
        if(!idx[i]) tarjan(i);

    simplifica_graf();

    fscanf(f, "%d", &t);
    for(int i = 1; i <= t; i++) {
        fscanf(f, "%d%d", &x, &y);
        //loc[i].x = x; loc[i].y = y; loc[i].ind = i;
        if(ctc[x] == ctc[y]) fprintf(g, "%d\n", 0);
        else {
            bf(ctc[x]);
            fprintf(g, "%d\n", cost[ctc[y]]);
        }
    }

   /*sort(loc + 1, loc + t + 1, comp);

    int ux = 0;
    for(int i = 1; i <= t; i++) {
        x = loc[i].x; y = loc[i].y;
        if(ctc[x] != ctc[y]) {
            if(ctc[ux] != ctc[x]) bf(ctc[x]);
            rez[loc[i].ind] = cost[ctc[y]];
        }
        else rez[loc[i].ind] = 0;
        ux = x;
    }

    for(int i = 1; i <= t; i++) fprintf(g, "%d\n", rez[i]);*/

    fclose(f); fclose(g);

    return 0;
}