Cod sursa(job #2962366)

Utilizator refugiatBoni Daniel Stefan refugiat Data 8 ianuarie 2023 14:13:51
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
ifstream si("cuplaj.in");
ofstream so("cuplaj.out");
vector<int> viz, par;
vector<vector<int> > graph;
struct edge
{
    int x, y, cap, poz;
};

vector<edge> edges;

int n, cap, src, dest, l, r;

int bfs()
{
    par.clear();
    par.resize(n);
    fill(viz.begin(), viz.end(), 0);
    queue<int> que;
    que.push(src);
    viz[src] = 1;
    while (!que.empty())
    {
        int nod = que.front();
        que.pop();
        if (nod == dest)
            continue;
        for (int i = 0; i < graph[nod].size(); ++ i)
        {
            edge curr = edges[graph[nod][i]];
            if (!viz[curr.y] && curr.cap != 0)
            {
                viz[curr.y] = 1;
                par[curr.y] = graph[nod][i];
                que.push(curr.y);
            }
        }
    }
    return viz[dest];
}


int main()
{
    si >> l >> r >> cap;

    n = l + r + 2;

    src = 0;
    dest = n - 1;

    viz.resize(n);
    par.resize(n);
    graph.resize(n);

    for(int i = 1; i <= cap; i++)
    {
        int x, y;
        si >> x >> y;
        edges.push_back({x, y + l, 1, 2 * i - 1});
        edges.push_back({y + l, x, 0, 2 * i - 2});
        graph[y + l].push_back(2 * i - 1);
        graph[x].push_back(2 * i - 2);
    }

    int ed = edges.size();

    for (int i = 1; i <= l; i++)
    {
        ed += 2;
        edges.push_back({src, i, 1, ed - 1});
        graph[i].push_back(ed - 1);
        edges.push_back({i, src, 0, ed - 2});
        graph[src].push_back(ed - 2);
    }

    for (int i = l + 1; i < n - 1; i++)
    {
        ed += 2;
        edges.push_back({i, dest, 1, ed - 1});
        graph[dest].push_back(ed - 1);
        edges.push_back({dest, i, 0, ed - 2});
        graph[i].push_back(ed - 2);
    }


    int flow = 0;
    while (bfs())
    {
        for (int i = 0; i < graph[dest].size(); ++ i)
        {
            if (viz[edges[graph[dest][i]].y] && edges[edges[graph[dest][i]].poz].cap != 0)
            {
                int fc = 2000000000;
                edge curr = edges[graph[dest][i]];
                par[dest] = curr.poz;
                int nod = dest;
                while (nod != src)
                {
                    fc = min(fc, edges[par[nod]].cap);
                    nod = edges[par[nod]].x;
                }

                nod = dest;
                while (nod != src)
                {
                    edges[par[nod]].cap -= fc;
                    edges[edges[par[nod]].poz].cap += fc;
                    nod = edges[par[nod]].x;
                }

                flow += fc;
            }
        }
    }

    so << flow << '\n';

    for (int i = 0; i < edges.size(); ++ i)
        if (edges[i].cap == 0 && edges[i].x != src && edges[i].y != dest && edges[i].x < edges[i].y)
            so << edges[i].x << ' ' << edges[i].y - l << '\n';
    return 0;
}