Cod sursa(job #2955367)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 16 decembrie 2022 20:50:06
Problema Cuplaj maxim in graf bipartit Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.04 kb
#include <fstream>
#include <queue>
using namespace std;

const int NMAX = 1000;
int N, M, capacity[NMAX + 2][NMAX + 2], flow[NMAX + 2][NMAX + 2], parent[NMAX + 2];
vector <int> graph[NMAX + 2];
bool seen[NMAX + 2];

bool BFS() {
    for(int i = 1; i <= N; i++) {
        seen[i] = false;
        parent[i] = 0;
    }
    queue <int> q; q.push(1);
    seen[1] = true;
    while(!q.empty()) {
        int node = q.front(); q.pop();
        for(int it : graph[node]) {
            if(flow[node][it] < capacity[node][it] && !seen[it]) {
                seen[it] = true, parent[it] = node;
                q.push(it);
            }
        }
    }
    return seen[N];
}

int main() {
    ifstream f("cuplaj.in"); ofstream g("cuplaj.out");
    int l, r;
    f >> l >> r >> M;
    N = 2 + l + r;
    for(int i = 1; i <= M; i++) {
        int x, y; f >> x >> y;
        x++; y = l + 1 + y;
        graph[x].push_back(y), graph[y].push_back(x);
        capacity[x][y] = 1;
    }
    for (int i = 2; i <= l + 1; i++) {
        graph[1].push_back(i); graph[i].push_back(1);
        capacity[1][i] = 1;
    }
    for (int i = 1; i <= r; i++) {
        graph[l + 1 + i].push_back(2 + l + r); graph[2 + l + r].push_back(l + 1 + i);
        capacity[l + 1 + i][2 + l + r] = 1;
    }
    while(BFS()) {
        for(int pv : graph[N]) {
            int pumpFlow = capacity[pv][N] - flow[pv][N];
            for(int node = pv; node != 1; node = parent[node]) {
                pumpFlow = min(pumpFlow, capacity[parent[node]][node] - flow[parent[node]][node]);
            }
            flow[pv][N] += pumpFlow, flow[N][pv] -= pumpFlow;
            for(int node = pv; node != 1; node = parent[node]) {
                flow[parent[node]][node] += pumpFlow, flow[node][parent[node]] -= pumpFlow;
            }
        }
    }
    int ans = 0;
    for(int i = 2; i <= l + 1; i++) { ans += flow[1][i]; }
    g << ans << '\n';

    for (int i = 2; i <= l + 1; i++) {
        for (int x : graph[i]) {
            if (flow[i][x] == 1) { g << i - 1 << ' ' << x - l - 1 << '\n'; }
        }
    }
    return 0;
}