Cod sursa(job #3328614)

Utilizator MihneaDobrinDobrin Mihnea-Gabriel MihneaDobrin Data 9 decembrie 2025 13:27:26
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 10000;

int capacitate[NMAX+1][NMAX+1];
int flux[NMAX+1][NMAX+1];
int vis[NMAX+1], p[NMAX+1];
vector<int> G[NMAX+1];
int n_total;

int bfs(int s, int d) {
    for(int i=1; i<=n_total; i++) {
        vis[i] = 0;
        p[i] = 0;
    }
    queue<int> q;
    q.push(s);
    vis[s]=1;
    while(!q.empty()) {
        int nod = q.front();
        q.pop();
        for(auto vecin : G[nod]) {
            if(!vis[vecin] && capacitate[nod][vecin] - flux[nod][vecin] > 0) {
                vis[vecin] = 1;
                p[vecin] = nod;
                q.push(vecin);
            }
        }
    }
    if(!vis[d]) {
        return 0;
    }

    vector<int> path;
    int x = d;
    while(x != 0 && x != s) {
        path.push_back(x);
        x = p[x];
    }
    path.push_back(s);
    reverse(path.begin(), path.end());

    int flow = 1e9;
    for(int i=0; i<path.size()-1; i++) {
        int a = path[i];
        int b = path[i+1];
        flow = min(flow, capacitate[a][b] - flux[a][b]);
    }
    for(int i=0; i<path.size()-1; i++) {
        int a = path[i];
        int b = path[i+1];
        flux[a][b] += flow;
        flux[b][a] -= flow;
    }
    return flow;
}

void adauga_muchie(int x, int y, int cap) {
    capacitate[x][y]=cap;
    G[x].push_back(y);
    G[y].push_back(x);
}

int main() {
    ifstream cin("cuplaj.in");
    ofstream cout("cuplaj.out");
    int N,M,E;
    cin>>N>>M>>E;
    int S=N+M+1;
    int D=N+M+2;
    n_total=D;
    for(int i=1;i<=E;i++)
    {
        int u,v;
        cin>>u>>v;
        adauga_muchie(u,N+v,1);
    }
    for(int i=1;i<=N;i++){
        adauga_muchie(S,i,1);
    }
    for(int i=1;i<=M;i++) {
        adauga_muchie(N+i,D,1);
    }
    int maxflow=0;
    while(true) {
        int flow=bfs(S, D);
        if(flow==0)
            break;
        maxflow+=flow;
    }

    cout<<maxflow<<'\n';
    for(int i=1;i<=N;i++) {
        for(auto vecin : G[i]) {
            if(vecin>N && vecin<=N+M) {
                if(flux[i][vecin]==1) {
                    cout<<i<<" "<<(vecin-N)<<'\n';
                }
            }
        }
    }

    return 0;
}