Cod sursa(job #3329888)

Utilizator code_blocksSpiridon Mihnea-Andrei code_blocks Data 16 decembrie 2025 12:47:59
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.8 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int NMAX = 10009;
const int HIGH = 1000001;

struct graph
{
    int N, M, flow[NMAX][NMAX], cap[NMAX][NMAX];
    vector<int> A[NMAX];

    void ae(int x, int y, int c)
    {
        G.cap[x][y] = c;
        G.A[x].push_back(y);
        G.A[y].push_back(x);
    }
} G;

struct flow_bfs
{
    bool viz[NMAX];
    int tata[NMAX], sent_flow;

    void clear(int N)
    {
        sent_flow = HIGH;
        for(int i = 1; i <= N; i++)
            viz[i] = false, tata[i] = 0;
    }

    void find_path(graph& G, int s, int t)
    {
        clear(G.N);
        
        queue<int> q;
        q.push(s);
        viz[s] = true;

        while(!q.empty())
        {
            int n = q.front();
            q.pop();

            for(const auto& v : G.A[n])
            {
                if(!viz[v] && G.cap[n][v] - G.flow[n][v] > 0)
                {
                    viz[v] = true;
                    q.push(v);
                    tata[v] = n;
                }
            }
        }
    }

    void run(graph& G, int s, int t)
    {
        find_path(G, s, t);

        if(viz[t] == 0)
            sent_flow = 0;
        else
        {
            vector<int> path;
            while(t != 0)
            {
                path.push_back(t);
                t = tata[t];
            }

            reverse(path.begin(), path.end());

            for(int i = 0; i < path.size() - 1; i++)
            {
                int x = path[i], y = path[i + 1];
                sent_flow = min(sent_flow, G.cap[x][y] - G.flow[x][y]);
            }

            for(int i = 0; i < path.size() - 1; i++)
            {
                int x = path[i], y = path[i + 1];
                G.flow[x][y] += sent_flow;
                G.flow[y][x] -= sent_flow;
            }
        }
    }
};

int edmonds_karp(graph& G, int s, int t)
{
    flow_bfs B;
    int max_flow = 0;
    
    do
    {
        B.run(G, s, t);
        max_flow += B.sent_flow;
    }
    while(B.sent_flow > 0);

    return max_flow;
}

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

    int NL, NR;

    fin >> NL >> NR >> G.M;

    int s = NL + NR + 1;
    int t = NL + NR + 2;
    G.N = NL + NR + 2;

    for(int i = 1; i <= G.M; i++)
    {
        int x, y;
        fin >> x >> y;
        y += NL;

        G.ae(x, y, 1);
    }

    for(int i = 1; i <= NL; i++)
        G.ae(s, i, 1);

    for(int i = NL + 1; i <= NL + NR; i++)
        G.ae(i, t, 1);

    int edges_placed = edmonds_karp(G, s, t);
    fout << edges_placed << '\n';

    for(int i = 1; i <= G.N - 2; i++)
        for(int j = 1; j <= G.N - 2; j++)
            if(G.flow[i][j] > 0)
                fout << i << ' ' << j - NL << '\n';

    fin.close();
    fout.close();

    return 0;
}