Cod sursa(job #2333108)

Utilizator Valentin0709Datcu George Valentin Valentin0709 Data 31 ianuarie 2019 18:22:03
Problema Obiective Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;

#define NMAX 32005

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

int n, m, t, x, y, index, ssize, nrctc, ctc[NMAX], viz[NMAX], cost[NMAX], s[NMAX], idx[NMAX], lowlink[NMAX], onstack[NMAX];

struct nod {
    int inf;
    nod* urm;
} *l[NMAX], *ls[NMAX], *sol[NMAX];

void adaug_nod(nod* &l, int x) {
    nod* p = new nod;

    p->inf = x;
    p->urm = l;
    l = p;
}

int exista_strada(int x, int y, nod* lista[]) {
    for(nod* p = lista[x]; p != NULL; p = p->urm)
        if(p->inf == y) return 1;

    return 0;
}

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);
        adaug_nod(l[x], y);
    }
}

void tarjan(int v) {
    int x;

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

    for(nod* p = l[v]; p != NULL; p = p->urm) {
        int u = p->inf;
        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];
            adaug_nod(sol[nrctc], x);
            ctc[x] = nrctc;
            onstack[x] = 0; ssize--;
        } while(x != v);
    }
}

void drum_ctc(int i, int j) {
    for(nod* p1 = sol[i]; p1 != NULL; p1 = p1->urm) {
        int x = p1->inf;
        for(nod* p2 = sol[j]; p2 != NULL; p2 = p2->urm) {
            int y = p2->inf;
            if(exista_strada(x, y, l)) {
                adaug_nod(ls[i], j);
                return;
            }
            if(exista_strada(y, x, l)) {
                adaug_nod(ls[j], 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 df(int x) {
    viz[x] = 1;

    for(int i = 1; i <= nrctc; i++) {
        if(exista_strada(x, i, ls) && !viz[i]) {
            cost[i] = cost[x];
            df(i);
        }
        if(exista_strada(i, x, ls) && !viz[i]) {
            cost[i] = cost[x] + 1;
            df(i);
        }
    }
}

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);

        memset(cost, 0, sizeof(cost));
        memset(viz, 0, sizeof(viz));
        df(ctc[x]);
        fprintf(g, "%d\n", cost[ctc[y]]);
    }

    fclose(f); fclose(g);

    return 0;
}