Cod sursa(job #2962230)

Utilizator witekIani Ispas witek Data 8 ianuarie 2023 01:15:46
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.48 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

struct Edge {
    int x, y, cap, poz;
};

int n, m, e, s, t;
vector <Edge> edges;
vector <vector<int>> v;
vector <int> parrent;
vector <bool> visited;

void init() {
    v = vector <vector<int>> (n + m + 2);
    parrent = vector <int> (n + m + 2);
    visited = vector <bool> (n + m + 2);
}

void addEdge(int x, int y) {
    int dim = edges.size();
    v[x].push_back(dim);
    v[y].push_back(dim + 1);
    edges.push_back({x, y, 1, dim + 1});
    edges.push_back({y, x, 0, dim});
}

void read() {
    fin >> n >> m >> e;
    t = n + m + 1;
    init();
    int x, y;
    for(int i = 1; i <= e; i ++) {
        fin >> x >> y;
        addEdge(x, y + n);
    }
    for(int i = 1; i <= n; i ++)
        addEdge(s, i);
    for(int i = n + 1; i <= n + m; i ++)
        addEdge(i, n + m + 1);
}

bool bfs() {
    fill(visited.begin(), visited.end(), 0);
    fill(parrent.begin(), parrent.end(), 0);
    queue <int> q;
    q.push(s);
    visited[s] = true;
    int node;
    while(!q.empty()) {
        node = q.front();
        q.pop();
        if(node == t)
            continue;
        for(const auto& i : v[node]) {
            auto edge = edges[i];
            if(!visited[edge.y] && edge.cap) {
                parrent[edge.y] = i;
                visited[edge.y] = true;
                q.push(edge.y);
            }
        }
    }
    return visited[t];
}

int getMaxFlow() {
    int ansFlow = 0;
    while(bfs()) {
        for(const auto& i : v[t]) {
            if(!visited[edges[i].y])
                continue;
            auto edge = edges[i];
            parrent[t] = edge.poz;
            int minFlow = 2e9;
            for (int node = t; node != s; node = edges[parrent[node]].x) {
                if (edges[parrent[node]].cap < minFlow)
                    minFlow = edges[parrent[node]].cap;
            }
            if(minFlow == 0)
                continue;
            ansFlow += minFlow;
            for (int node = t; node != s; node = edges[parrent[node]].x) {
                edges[parrent[node]].cap -= minFlow;
                edges[edges[parrent[node]].poz].cap += minFlow;

            }
        }
    }
    return ansFlow;
}


int main() {
    read();
    fout << getMaxFlow() << '\n';
    for(auto edge : edges)
        if(edge.x < edge.y && edge.x != s && edge.y != t && edge.cap == 0)
            fout << edge.x << " " << edge.y - n << '\n';
    return 0;
}