Cod sursa(job #2961171)

Utilizator lucianul31Moisii Lucian lucianul31 Data 5 ianuarie 2023 22:46:19
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <string.h>

using namespace std;

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

const int NMAX = 1e5 + 5;
int Father[NMAX], N, M, E, Source, Destination, TotalFlow;
bool Seen[NMAX];
unordered_map < int, int > Edges[NMAX];
queue < int > Q;

int BFS()
{
    int X, Flow = 0, Bottleneck;
    Father[0] = -1;
    memset(Seen, 0, sizeof(int) * (Destination + 1));
    Seen[0] = 1;
    Q.push(0);
    while(!Q.empty())
    {
        X = Q.front();
        Q.pop();
        for(auto& newX : Edges[X])
        {
            if(newX.first == Destination)
                continue;
            if(!Seen[newX.first] && Edges[X][newX.first] > 0)
                Q.push(newX.first), Seen[newX.first] = 1, Father[newX.first] = X;
        }
    }
    for(int i = N + 1; i < Destination; i++)
    {
        if(!Seen[i])
            continue;
        X = i;
        Bottleneck = Edges[X][Destination];
        while(Father[X] != -1)
        {
            Bottleneck = min(Bottleneck, Edges[Father[X]][X]);
            X = Father[X];
        }
        // if(Bottleneck == 0)
        //     continue;
        Flow += Bottleneck;
        X = i;
        Edges[X][Destination] -= Bottleneck;
        Edges[Destination][X] += Bottleneck;
        while(Father[X] != -1)
        {
            Edges[Father[X]][X] -= Bottleneck;
            Edges[X][Father[X]] += Bottleneck;
            X = Father[X];
        }
    }
    return Flow;
}

void MaxFlow()
{
    int c = BFS();
    while(c)
    {
        TotalFlow += c;
        c = BFS();
    }
}

int main()
{
    std::ios::sync_with_stdio(false);
    in.tie(NULL);
    out.tie(NULL);
    int x, y;
    in >> N >> M >> E;
    Destination = N + M + 1;
    for(int i = 1; i <= E; i++)
    {
        in >> x >> y;
        y += N;
        Edges[x][y] = 1;
        Edges[y][x] = 0;
    }
    for(int i = 1; i <= N; i++)
        Edges[0][i] = 1;
    for(int i = N + 1; i < Destination; i++)
        Edges[i][Destination] = 1;
    MaxFlow();
    out << TotalFlow << '\n';
    for(int i = 1; i <= N; i++)
        for(auto& it : Edges[i])
            if(!Edges[i][it.first] && it.first)
            {
                out << i << ' ' << it.first - N << '\n';
                break;
            }
    return 0;

}