Cod sursa(job #3329893)

Utilizator mirudragunoiDragunoi Miruna mirudragunoi Data 16 decembrie 2025 12:50:43
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

const int NMAX = 20010;
const int EMAX = 200010;

struct Edge {
    int to, cap, flow, rev;
};

vector<Edge> G[NMAX];
int vis[NMAX], p_node[NMAX], p_edge[NMAX];
int n, m, e;

void addEdge(int from, int to, int cap) {
    G[from].push_back({to, cap, 0, (int)G[to].size()});
    G[to].push_back({from, 0, 0, (int)G[from].size() - 1});
}

int bfs(int s, int d) {
    memset(vis, 0, sizeof(vis));
    memset(p_node, -1, sizeof(p_node));

    queue<int> q;
    q.push(s);
    vis[s] = 1;

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

        for(int i = 0; i < (int)G[nod].size(); i++) {
            Edge &ed = G[nod][i];
            if(!vis[ed.to] && ed.cap - ed.flow > 0) {
                vis[ed.to] = 1;
                q.push(ed.to);
                p_node[ed.to] = nod;
                p_edge[ed.to] = i;
            }
        }
    }

    if(!vis[d]) return 0;
    
    int flow = 1e9;
    int curr = d;
    while(curr != s) {
        int prev = p_node[curr];
        int edge_idx = p_edge[curr];
        flow = min(flow, G[prev][edge_idx].cap - G[prev][edge_idx].flow);
        curr = prev;
    }

    curr = d;
    while(curr != s) {
        int prev = p_node[curr];
        int edge_idx = p_edge[curr];
        G[prev][edge_idx].flow += flow;
        G[curr][G[prev][edge_idx].rev].flow -= flow;
        curr = prev;
    }

    return flow;
}

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

    cin >> n >> m >> e;

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

    for(int i = 1; i <= n; i++) {
        addEdge(sursa, i, 1);
    }

    for(int i = 1; i <= m; i++) {
        int nod_r = n + i;
        addEdge(nod_r, dest, 1);
    }

    for(int i = 0; i < e; i++) {
        int u, v;
        cin >> u >> v;
        int nod_r = n + v;
        addEdge(u, nod_r, 1);
    }

    int maxflow = 0;
    int flow;
    while((flow = bfs(sursa, dest)) > 0) {
        maxflow += flow;
    }

    cout << maxflow << "\n";

    for(int i = 1; i <= n; i++) {
        for(auto &ed : G[i]) {
            if(ed.to > n && ed.to <= n + m && ed.flow == 1) {
                cout << i << " " << (ed.to - n) << "\n";
            }
        }
    }

    return 0;
}