Cod sursa(job #2962699)

Utilizator AlexPascu007Pascu Ionut Alexandru AlexPascu007 Data 8 ianuarie 2023 23:13:24
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.36 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;

struct muchie {
    int out, in, cap, index;
};
vector<muchie> muchii;
vector<vector<int>> graf;
int bfs() {
    f.reset();
    q.push(0), f[0] = 1;
    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        for (auto it : graf[nod]) {
            muchie m = muchii[it];
            if (f[m.in] == 0 && m.cap > 0) {
                f[m.in] = 1;
                q.push(m.in);
                t[m.in] = nod;
            }
        }
    }
    return f[n + m + 1];
}

int main() {
    fin >> n >> m >> e;
    for (i = 1; i <= e; i++) {
        fin >> x >> y;
        muchie muchie_normala = {x, y + n, 1, 2 * i - 1};
        muchii.push_back(muchie_normala);
        graf[x].push_back(2 * i - 1);
        muchie muchie_intoarcere = {y + n, x, 0, 2 * i - 2};
        muchii.push_back(muchie_intoarcere);
        graf[y + n].push_back(2 * i - 2);
    }

    // conectam sursa la nodurile din stanga
    for (i = 1; i <= n; i++) {
        muchie muchie_normala = {0, i, 1, 2 * e + 2 * i - 1};
        muchie muchie_intoarcere = {i, 0, 0, 2 * e + 2 * i - 2};
        muchii.push_back(muchie_normala);
        muchii.push_back(muchie_intoarcere);
        graf[0].push_back(2 * e + 2 * i - 1);
        graf[i].push_back(2 * e + 2 * i - 2);
    }

    // conectam muchiile din dreapta la destinatie
    for (i = 1; i <= m; i++) {
        muchie muchie_normala = {i + n, n + m + 1, 1, 2 * e + 2 * n + 2 * i - 1};
        muchie muchie_intoarcere = {n + m + 1, i + n, 0, 2 * e + 2 * n + 2 * i - 2};
        muchii.push_back(muchie_normala);
        muchii.push_back(muchie_intoarcere);
        graf[i + n].push_back(2 * e + 2 * n + 2 * i - 1);
        graf[n + m + 1].push_back(2 * e + 2 * n + 2 * i - 2);

    }
    fluxtotal = 0;
    while (bfs()) {
        for (auto it : graf[n + m + 1]) {
            muchie muchie = muchii[it];
            if (f[muchie.in] == 1 && muchii[muchie.index].cap > 0) {
                int nod = n + m + 1;
                t[nod] = muchie.index;
                int fluxmin = INT_MAX;
                while (nod != 0) {
                    if (muchii[t[nod]].cap < fluxmin) {
                        fluxmin = muchii[t[nod]].cap;
                    }
                    nod = muchii[t[nod]].out;
                }
                nod = n + m + 1;
                while (nod != 0) {
                    muchii[t[nod]].cap -= fluxmin;
                    muchii[muchii[t[nod]].index].cap += fluxmin;
                    nod = muchii[t[nod]].out;
                }
                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 = 0; i < muchii.size(); i += 2) {
        if (muchii[i].cap == 0 && muchii[i].out != 0 && muchii[i].in != n + m + 1) {
            fout << muchii[i].out << ' ' << muchii[i].in - n << '\n';
        }
    }

    return 0;
}