Cod sursa(job #2962656)

Utilizator AlexPascu007Pascu Ionut Alexandru AlexPascu007 Data 8 ianuarie 2023 22:27:16
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include <bits/stdc++.h>
#define DIM 20010
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
//int n, m, e, i, x, y, z, fluxmin, fluxtotal, nod, vecin, t[DIM], cap[2*DIM][2*DIM], flux[2*DIM][2*DIM];
int n, m, e, i, x, y, z, fluxmin, fluxtotal, nod, vecin;
vector<int> L[DIM], t;
vector<vector<int>> cap, flux;
queue<int> q;
bitset<DIM> f;


int bfs() {
    f.reset();
    q.push(0), f[0] = 1;
    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        for (auto vecin : L[nod]) {
            if (f[vecin] == 0 && cap[nod][vecin] > flux[nod][vecin]) {
                f[vecin] = 1;
                q.push(vecin);
                t[vecin] = nod;
            }
        }
    }
    return f[n + m + 1];
}

int main() {
    fin >> n >> m >> e;
    flux.resize(2 * (n + m + 2), vector<int>(2 * (n + m + 2), 0));
    cap.resize(2 * (n + m + 2), vector<int>(2 * (n + m + 2), 0));
    t.resize(2 * (n + m + 2), 0);
    for (i = 1; i <= e; i++) {
        fin >> x >> y;
        L[x].push_back(n + y);
        L[n + y].push_back(x);
        cap[x][n + y] = 1;
    }

    // conectam sursa la nodurile din stanga
    for (i = 1; i <= n; i++) {
        L[0].push_back(i);
        L[i].push_back(0);
        cap[0][i] = 1;
    }

    // conectam muchiile din dreapta la destinatie
    for (i = 1; i <= m; i++) {
        L[n + i].push_back(n + m + 1);
        L[n + m + 1].push_back(n + i);
        cap[n + i][n + m + 1] = 1;
    }

    while (bfs()) {
        fluxmin = INT_MAX;
        for (nod = n + m + 1; nod != 0; nod = t[nod]) {
            vecin = t[nod];
            fluxmin = min(fluxmin, cap[vecin][nod] - flux[vecin][nod]);
        }
        for (nod = n + m + 1; nod != 0; nod = t[nod]) {
            vecin = t[nod];
            flux[vecin][nod] += fluxmin;
            flux[nod][vecin] -= fluxmin;
        }
        fluxtotal += fluxmin;
    }
    // fluxul maxim este egal cu cuplajul maxim
    fout << fluxtotal << '\n';

    // afisam muchiile saturate, acestea sunt cele care fac parte din cuplaj
    for (i = 1; i <= n; i++) {
        for (auto vecin : L[i]) {
            if (vecin != 0 && flux[i][vecin] == 1) {
                fout << i << ' ' << vecin - n << '\n';
            }
        }
    }

    return 0;
}