Cod sursa(job #3330309)

Utilizator StefanL2005Stefan Leustean StefanL2005 Data 18 decembrie 2025 17:40:52
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.85 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");

#define inf 1e9

vector<int> Tata;
vector<bool> Visited;

bool Find_BFS(int nod, int dest, auto &vecini_rezid, auto& cap_rezid) {

    Visited.assign(vecini_rezid.size(), false);
    //Tata.assign(vecini.size(), -1);
    queue<int> Q;

    Visited[nod] = true;
    Q.push(nod);

    while (!Q.empty()) {
        nod = Q.front();
        Q.pop();

        for (int v : vecini_rezid[nod]) {
            if (Visited[v]) continue;
            if (cap_rezid[nod][v]  <= 0) continue;

            Tata[v] = nod;
            Visited[v] = true;
            Q.push(v);

            if (v == dest)
                return true;
        }

    }
    return false;
}
int Min_Cap_Lant(int sursa, int dest, auto& cap_rezid) {
    int c = dest, cap_min = inf;
    while (c != sursa) {
        int tc = Tata[c];
        cap_min = min(cap_min, cap_rezid[tc][c] );
        c = tc;
    }

    return cap_min;
}
void Upd_Flux_Lant(int sursa, int dest, int cap_min, auto& cap_rezid) {
    int c = dest;

    while (c != sursa) {
        int tc = Tata[c];
        cap_rezid[tc][c] -= cap_min; //trimit flux -> scade capac reziduala
        cap_rezid[c][tc] += cap_min;
        c = tc;
    }
}

int main()
{
    int n, m, e;
    in >> n >> m >> e;

    vector<vector<int>> vecini_rezid;
    vector<vector<int>> capac_rezid;
    Tata.assign(n+m+2, 0);
    vecini_rezid = vector<vector<int>> (n+m+2);
    capac_rezid = vector<vector<int>> (n+m+2, vector<int> (n+m+2, 0));

    int sursa = 0, dest = n + m + 1, flux_max = 0;

    for (int i = 0; i < e; i++) {
        int x, y;
        in >> x >> y;
        y=y+n;

        capac_rezid[x][y] = 1;
        vecini_rezid[x].push_back(y);
        vecini_rezid[y].push_back(x);
    }
    for(int i=1; i<=n; i++){

        capac_rezid[sursa][i] = 1;
        vecini_rezid[sursa].push_back(i);
        vecini_rezid[i].push_back(sursa);

    }

    for(int i=n+1; i<=n+m; i++){

        capac_rezid[i][dest] = 1;
        vecini_rezid[i].push_back(dest);
        vecini_rezid[dest].push_back(i);

    }

    /*
        Cat timp bfs-ul din surs in destinatie gaseste un drum
        Determinam capacitatea minima (vectorul de tati) -> min
        Pe acelasi drum modificam fluxul cu min
    */

    while (Find_BFS(sursa, dest, vecini_rezid,capac_rezid)) {
        int cap_min = Min_Cap_Lant(sursa, dest, capac_rezid);
        Upd_Flux_Lant(sursa, dest, cap_min, capac_rezid);

        flux_max += cap_min;
    }

    out << flux_max << "\n";

    for(int i = 1; i<=n; i++){
        for(int j=n+1; j<=n+m; j++){
            if(capac_rezid[j][i] == 1)
                out<<i<<" "<<j-n<<'\n';
        }
    }



    return 0;
}