Cod sursa(job #3334682)

Utilizator tudorbarbuTudor Barbu tudorbarbu Data 19 ianuarie 2026 00:53:33
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.23 kb
#include <fstream>
#include<vector>
#include <queue>
#define inf 1e9
using namespace std;

ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");

int N, M, E;
int source = 0;
int sink;
vector<vector<int>> graph;
vector<vector<int>> cuplaj;
vector<bool> viz;
vector<int> tata;
int total_value;
int cuplaj_maxim;

bool bfs() {
    tata.assign(total_value, 0);
    viz.assign(total_value, 0);
    viz[source] = 1;
    queue<pair<int,int>> q;
    q.push({source, inf});
    while (!q.empty()) {
        int top = q.front().first;
        int flow = q.front().second;
        q.pop();
        for (auto e : graph[top]) {
            if ( !viz[e] && cuplaj[top][e] > 0) {
                tata[e] = top;
                viz[e] = 1;
                int pushed = min(flow, cuplaj[top][e]);
                if (e == sink)
                    return true;
                q.push({e, pushed});
            }
        }
    }
    return false;
}

int Edmunds_karp() {
    while (bfs()) {
        int bottleneck = inf;
        int current = sink;
        while (current != source) {
            int prev = tata[current];
            bottleneck = min(bottleneck, cuplaj[prev][current]);
            current = prev;
        }
        current = sink;
        while (current != source) {
            int prev = tata[current];
            cuplaj[prev][current] -= bottleneck;
            cuplaj[current][prev] += bottleneck;
            current = prev;
        }
        cuplaj_maxim +=bottleneck;
    }
    return cuplaj_maxim;
}


/*
 *FORD FULKERSON

int dfs(int node, int flux_curent) {
    if (node == sink) return flux_curent;

    viz[node] = true;

    for (auto e : graph[node]) {
        if (!viz[e] && cuplaj[node][e] > 0) {
            int bottleneck = min(flux_curent, cuplaj[node][e]);
            int flux_pushed = dfs(e, bottleneck);

            if (flux_pushed > 0) {
                cuplaj[node][e] -= flux_pushed;
                cuplaj[e][node] += flux_pushed;
                return flux_pushed;
            }
        }
    }
    return 0;
}
*/


int main() {
    cin >> N >> M >> E;
    total_value = N + M + 2;
    graph.resize(total_value);
    cuplaj.resize(total_value);
    viz.resize(total_value);
    sink = N + M + 1;

    for (int i = 0; i <= N + M + 1; i++)
        cuplaj[i].resize(total_value);

    for (int i = 0; i < E; i++) {
        int u, v;
        cin >> u >> v;
        //legam muchiile
        graph[u].push_back(N + v);
        graph[N + v].push_back(u);

        // legam sursa de nodurile din L
        graph[source].push_back(u);
        graph[u].push_back(source);

        //legam nodurile din R de sink
        graph[N+v].push_back(sink);
        graph[sink].push_back(N+v);

        //adaugam capacitatile
        cuplaj[u][N + v] = 1;
        cuplaj[source][u] = 1;
        cuplaj[N + v][sink] = 1;
    }



    // ford fulkerson
    /*
    while (true) {
        viz.assign(N+M+2, false);
        int pushed = dfs(source, 1e9);
        if (!pushed)
            break;
        cuplaj_maxim += pushed;
    }
*/
    cout << Edmunds_karp() << endl;
    // reconstruirea drumului

    for (int i = 1; i <= N; i++)
        for (auto e : graph[i]) {
            if (e > N && e < sink && cuplaj[i][e] == 0)
                cout << i << " " << e - N << "\n";
        }
    return 0;
}