Cod sursa(job #3270805)

Utilizator radiantstorkAmadeus L radiantstork Data 24 ianuarie 2025 15:19:16
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

void citire(std::vector<std::vector<int> > &graf, std::vector<std::vector<int> > &capacitate,
            std::vector<std::vector<int> > &flux, int &a, int &b, int &n) {
    int m;
    int u, v;
    std::ifstream f("cuplaj.in");
    // prima partitie are "a" varfuri, a doua partitie are "b" varfuri
    // includem 2 noduri in plus: S=0 si T=a+b+1
    // facem n = a + b + 2
    f >> a >> b >> m;
    n = a + b + 2;

    graf.resize(n - 1);
    capacitate.resize(n - 1, std::vector(n, 0));
    flux.resize(n - 1, std::vector(n, 0));
    while (m--) {
        f >> u >> v;
        capacitate[u][a + v] = 1;
        graf[u].push_back(a + v);
        graf[a + v].push_back(u);
    }
    f.close();

    // muchii de la S=0 la nodurile din prima partitie cu capacitate 1
    for (int i = 1; i <= a; ++i) {
        capacitate[0][i] = 1;
        graf[0].push_back(i);
        graf[i].push_back(0);
    }

    // muchii de la T=n-1 la nodurile din a doua partitie cu capacitate 1
    for (int i = a + 1; i <= a + b; ++i) {
        capacitate[i][n - 1] = 1;
        graf[i].push_back(n - 1);
        // graf[n - 1].push_back(i);
    }
}

bool bfs(std::vector<std::vector<int> > &graf, std::vector<std::vector<int> > &capacitate,
         std::vector<std::vector<int> > &flux, std::vector<int> &tata, const int n) {
    std::vector viz(n, false);
    std::queue<int> q;
    q.push(0);
    viz[0] = true;

    while (!q.empty()) {
        const int i = q.front();
        q.pop();
        for (const auto &j: graf[i])
            if (!viz[j])
                if (capacitate[i][j] != flux[i][j]) {
                    tata[j] = i;
                    if (j == n - 1)
                        return true;
                    q.push(j);
                    viz[j] = true;
                }
    }
    return false;
}

void edmondsKarp() {
    std::vector<std::vector<int> > graf;
    std::vector<std::vector<int> > capacitate;
    std::vector<std::vector<int> > flux;
    int a, b;
    int n;
    citire(graf, capacitate, flux, a, b, n);

    std::vector tata(n, -1);
    int fluxMaxim = 0;
    while (bfs(graf, capacitate, flux, tata, n)) {
        int aux = n - 1;
        flux[tata[aux]][aux] += 1;
        aux = tata[aux];
        while (tata[aux] != -1) {
            flux[tata[aux]][aux] += 1;
            flux[aux][tata[aux]] -= 1;
            aux = tata[aux];
        }
        std::ranges::fill(tata, -1);
        ++fluxMaxim;
    }

    std::ofstream g("cuplaj.out");
    g << fluxMaxim << "\n";
    for (int i = 1; i <= a; ++i)
        for (int j = a + 1; j <= n - 2; ++j)
            if (flux[i][j])
                g << i << " " << j - a << "\n";
    g.close();
}

int main() {
    edmondsKarp();
    return 0;
}