Cod sursa(job #2955997)

Utilizator RobertuRobert Udrea Robertu Data 18 decembrie 2022 14:58:54
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <bits/stdc++.h>
#define inf INT_MAX
#define dim 20020
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

/*
    Ajutor: https://www.infoarena.ro/flux-si-cuplaj
    Idee: Similar cu ce am facut la harta, adaugam un nou start si un final, orientam toate
    muchiile spre final si le dam o capacitate de 1. Raspunsul va fi dat de fluxul maxim, iar 
    muchiile din cuplaj vor fi cele saturate, aka au ramas cu capacitate 0.
*/
long long maxFlow = 0;
int tata[dim], n, m, x, y, e, nod, flow;
bool viz[dim];
vector< int > a[10010];

bool bfs() {
    queue<int> coada;
    memset(tata, 0, sizeof(tata));
    memset(viz, false, sizeof(viz));

    coada.push(0);
    viz[0] = true;
    tata[0] = -1;
    while(!coada.empty()) {
        int front = coada.front();
        coada.pop();

        if(front == n + m + 1) {
            return true;
        }

        for(int i = 1; i <= n + m + 1; i++) {
            if( !viz[i] &&  a[front][i] > 0) {
                coada.push(i);
                viz[i] = true;
                tata[i] = front;
            }
        }
    }
    return false;
}

int main() {
    fin >> n >> m >> e;

    for(int i = 0; i <= n + m + 1; i++)
        a[i].resize(n + m + 1, 0);

    for(int i = 0; i < e; i++) {
        fin >> x >> y;
         a[x][n + y] = 1;
    }

    for(int i = 1; i <= n; i++)
        a[0][i] = 1;

    for(int i = 1; i <= m; i++)
        a[n + i][n + m + 1] = 1;
    
    while(bfs()) {
        for(int i = 1; i <= m; i++) {
            if( viz[n + i] && a[n + i][n + m + 1] > 0 ) {
                flow = inf;
                tata[n + m + 1] = n + i;
                for(nod = n + m + 1; nod != 0; nod = tata[nod]) {
                    flow = min(flow, a[ tata[nod] ][nod]);
                }

                if(flow == 0) continue;

                for(nod = n + m + 1; nod != 0; nod = tata[nod]) {
                    a[ tata[nod] ][nod] -= flow;
                    a[nod][ tata[nod] ] += flow;
                }
                maxFlow += flow;
            }
        }
    }

    fout << maxFlow << '\n';
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if( a[i][n + j] == 0 && a[n + j][i] == 1) 
                fout << i << " " << j << '\n';

    return 0;
}