Cod sursa(job #2962519)

Utilizator AntoniaPopoviciAntonia-Adelina Popovici AntoniaPopovici Data 8 ianuarie 2023 18:02:01
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.1 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

// COMPLEXITATE TIMP: O(VE^2)
int n, m, e, s, t;
vector<bool> dreapta;
vector<pair<int, int>> parinte, noduri;
vector<vector<pair<int, pair<int, int>>>> graf;


bool BFS() {
    vector<bool> viz(t + 1);
    queue<int> coada;
    coada.push(s);
    viz[s] = true;
    parinte[s] = { -1, -1 };
    while (!coada.empty()) {
        int u = coada.front();
        coada.pop();
        if (u == t)
            continue;
        int i = 0;
        for (auto nod : graf[u]) {
            int v, cap; 
            v = nod.first;
            cap = nod.second.first;
            if (!viz[v] && cap) {
                parinte[v] = { u, i };
                viz[v] = true;
                coada.push(v);
            }
            i++;
        }
    }
    return viz[t];
}

long maxflow() {
    long maxFlow = 0;
    while (BFS()) {
        for (auto nod : noduri) {
            int u, v, i, j, distmin = 1;
            parinte[t] = nod;
            v = t;
            while (parinte[v].first != -1) {
                u = parinte[v].first;
                i = parinte[v].second;
                distmin = min(distmin, graf[u][i].second.first);
                v = u;
            }
            v = t;
            while (parinte[v].first != -1) {
                u = parinte[v].first;
                i = parinte[v].second;
                j = graf[u][i].second.second;
                graf[u][i].second.first -= distmin;
                graf[v][j].second.first += distmin;
                v = u;
            }
            maxFlow += distmin;
        }
    }
    return maxFlow;
}

int main() {
    fin >> n >> m >> e;
    s = 0;
    t = n + m + 1;
    graf.resize(t + 1);
    dreapta.resize(m + 1);
    parinte.resize(t + 1);

    for (int i = 1; i <= n; i++)
    {
        graf[s].push_back({ i, {1, graf[i].size()} });
        graf[i].push_back({ s, {0, graf[s].size() - 1} });
        if (i == t)
            noduri.emplace_back(s, graf[s].size() - 1);
    }

    for (int i = 1; i <= e; i++) {
        int u, v;
        fin >> u >> v;
        graf[u].push_back({ n + v, {1, graf[n + v].size()} });
        graf[n + v].push_back({ u, {0, graf[u].size() - 1} });
        if (n + v == t)
            noduri.emplace_back(u, graf[u].size() - 1);
        dreapta[v] = true;
    }
    for (int i = 1; i <= m; i++)
        if (dreapta[i])
        {
            graf[n + i].push_back({ t, {1, graf[t].size()} });
            graf[t].push_back({ n + i, {0, graf[n + i].size() - 1} });
            if (t == t)
                noduri.emplace_back(n + i, graf[n + i].size() - 1);
        }  

        fout << maxflow() << '\n';
        for (int i = 1; i <= n; i++)
            for (auto nod : graf[i]) {
                int u, v;
                u = nod.first;
                v = nod.second.first;
                if (u && v == 0 && u != t)
                    fout << i << " " << u - n << '\n';
            }
    return 0;
}