Cod sursa(job #2965872)

Utilizator popescumateicalinPopescu Matei Calin popescumateicalin Data 16 ianuarie 2023 14:12:50
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb
#include <fstream>
#include <queue>
#include <vector>

std::ifstream in("cuplaj.in");
std::ofstream out("cuplaj.out");

const int N = 20005, MAX = 1e+7;
int n, m, e, maxFlow, grid[N][N];
std::vector<std::vector<int>> list(N);
std::vector<int> repr(N), vis(N);

bool BFS()
{
    std::fill(vis.begin(), vis.end(), 0);
    std::fill(repr.begin(), repr.end(), -1);

    std::queue<int> Q;
    Q.push(0);
    // repr[0] = 0;
    vis[0] = 1;

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

        if (x == n + m + 1)
            return true;

        for (int v : list[x])
        {
            if (grid[x][v] <= 0 || vis[v])
                continue;
            Q.push(v);
            vis[v] = 1;
            repr[v] = x;
        }
    }
    return false;
}

int main()
{
    in >> n >> m >> e;
    for (int i = 1; i <= n; i++)
    {
        grid[0][i] = 1;
        list[0].push_back(i);
        list[i].push_back(0);
    }
    for (int i = n + 1; i <= n + m; i++)
    {
        grid[i][n + m + 1] = 1;
        list[i].push_back(n + m + 1);
        list[n + m + 1].push_back(i);
    }
    for (int i = 0; i < e; i++)
    {
        int x, y;
        in >> x >> y;
        grid[x][n + y] = 1;
        list[x].push_back(n + y);
        list[n + y].push_back(x);
    }

    while (BFS())
        for (int v : list[n + m + 1])
        {
            if (!vis[v])
                continue;

            int flow = MAX;

            repr[n + m + 1] = v;
            for (int i = n + m + 1; i; i = repr[i])
                flow = std::min(flow, grid[repr[i]][i]);

            for (int i = n + m + 1; i; i = repr[i])
            {
                grid[repr[i]][i] -= flow;
                grid[i][repr[i]] += flow;
            }
            maxFlow += flow;
        }

    out << maxFlow << '\n';
    for (int i = 1; i <= n; i++)
        for (int j = 1; j < list[i].size(); j++)
            if (!grid[i][list[i][j]])
                out << i << ' ' << list[i][j] - n << '\n';
    return 0;
}