Cod sursa(job #2962504)

Utilizator AntoniaPopoviciAntonia-Adelina Popovici AntoniaPopovici Data 8 ianuarie 2023 17:53:06
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.15 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
const int MAXN = 20001;


// COMPLEXITATE TIMP: O(VE^2)
struct muchie {
    int vec;
    int flux;
    int cap;
};

int distanta[MAXN];
int parinte[MAXN];
int s, t;
vector <pair <int, int> > input;
vector <muchie> v[MAXN];
vector <int> dist;
queue <int> q;

int n;

int esteMuchie(int x, int y)
{
    for (int i = 0; i < v[x].size(); i++)
        if (v[x][i].vec == y)
            return i;
    return -1;
}

bool BFS()
{
    for (int i = 1; i <= n; i++)
        distanta[i] = (1 << 30);
    distanta[s] = 0;
    q.push(s);
    while (!q.empty())
    {
        int nod = q.front();
        q.pop();
        if (nod == t)
            continue;
        for (auto m : v[nod])
        {
            if (distanta[m.vec] > distanta[nod] + 1 && m.flux < m.cap)
            {
                distanta[m.vec] = distanta[nod] + 1;
                parinte[m.vec] = nod;
                q.push(m.vec);
            }
        }
    }
    if (distanta[t] == (1 << 30))
        return 0;
    return 1;
}


int main()
{
    int m, e;
    fin >> n >> m >> e;
    int ninit = n;
    s = n + m + 1;
    t = n + m + 2;
    
    for (int i = 1; i <= e; i++)
    {
        int x, y;
        fin >> x >> y;
        v[x].push_back({ y + n, 0, 1 });
        v[y + n].push_back({ x, 0, 0 });
        input.push_back(make_pair(x, y));
    }

    for (int i = 1; i <= n; i++)
    {
        v[s].push_back({ i, 0, 1 });
        v[i].push_back({ s, 0, 0 });
    }

    for (int i = 1; i <= m; i++)
    {
        v[i + n].push_back({ t, 0, 1 });
        v[t].push_back({ i + n, 0, 0 });
    }
    n = n + m + 2;
    
    while (BFS())
    {
        for (auto j : v[t])
        {
            int index = esteMuchie(j.vec, t);
            if (distanta[j.vec] == (1 << 30) || v[j.vec][index].flux == v[j.vec][index].cap)
                continue;
            
            parinte[t] = j.vec;
            
            int act = t;
            while (parinte[act] != 0)
            {
                dist.push_back(act);
                act = parinte[act];
            }

            dist.push_back(act);
            reverse(dist.begin(), dist.end());
            int minflow = (1 << 30);
            for (int i = 0; i < dist.size() - 1; i++)
            {
                int aux = esteMuchie(dist[i], dist[i + 1]);
                minflow = min(minflow, v[dist[i]][aux].cap - v[dist[i]][aux].flux);
            }
            for (int i = 0; i < dist.size() - 1; i++)
            {
                v[dist[i]][esteMuchie(dist[i], dist[i + 1])].flux += minflow;
                v[dist[i + 1]][esteMuchie(dist[i + 1], dist[i])].flux -= minflow;
            }
        }
    }
    int gata = 0;

    for (auto j : v[s])
        gata = gata + j.flux;

    fout << gata << "\n";
    
    for (auto j : input)
        if (v[j.first][esteMuchie(j.first, j.second + ninit)].flux == 1)
            fout << j.first << " " << j.second << "\n";
    
    return 0;
}