Cod sursa(job #2900965)

Utilizator raulandreipopRaul-Andrei Pop raulandreipop Data 12 mai 2022 17:09:50
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <iostream>
#include <vector>
#include <queue>
#define f first
#define s second

using namespace std;

int n, m, e;
pair<int , int> adjList[10020][10020];
vector<vector<int>> adj;
int par[20020];
bool viz[20020];

int checkFlow (pair<int , int> edge)
{
    return adjList[edge.f][edge.s].s 
    - adjList[edge.f][edge.s].f;
}

void init ()
{
    for (int i = 0; i <= n + m + 1; i++)
    {
        par[i] = -1;
        viz[i] = 0;
    }
}

bool bfs ()
{
    queue<int> q;
    q.push(0);
    
    while (!q.empty())
    {
        int nod = q.front();
        viz[nod] = 1;
        if (nod == n + m + 1) return 1;
        q.pop();
        for (auto to : adj[nod])
        {
            if (!viz[to] && checkFlow({nod, to}))
            {
                q.push(to);
                par[to] = nod;
            }
        }
    }
    return 0;
}

int main ()
{
    cin >> n >> m >> e;
    adj.resize(n + m + 2);
    for (int i = 1; i <= e; i++)
    {
        int x, y; cin >> x >> y;
        adjList[x][n + y].s++;
        adjList[n + y][x].f--;
        adj[x].push_back(n + y);
        adj[n + y].push_back(x);
    }
    for (int i = 1; i <= n; i++)
    {
        adjList[0][i].s += 1;
        adjList[i][0].f -= 1;
        adj[0].push_back(i);
        adj[i].push_back(0);
    }
    
    for (int i = n + 1; i <= n + m; i++)
    {
        adjList[i][n + m + 1].s += 1;
        adjList[n + m + 1][i].f -= 1;
        adj[n + m + 1].push_back(i);
        adj[i].push_back(n + m + 1);
        
    }

    init();

    int ans = 0;

    while (bfs())
    {
        for (auto leaf : adj[n + m + 1])
        {
            if (par[leaf] != -1 && checkFlow({leaf, n + m + 1}))
            {
                int flux = checkFlow({leaf, n + m + 1});
                int v = leaf;
                while (v != 0)
                {
                    flux = min (flux, checkFlow({par[v], v}));
                    v = par[v];
                }
                v = leaf;
                while (v != 0)
                {
                    adjList[par[v]][v].f += flux;
                    adjList[v][par[v]].f -= flux;
                    v = par[v];
                }
                adjList[leaf][n + m + 1].f += flux;
                adjList[n + m + 1][leaf].f -= flux;
                ans += flux;
                
            }
        }
        init();
    }

    cout << ans << '\n';
 
  /*  for (int i = 1; i <= n; i++)
    {
        for (int j = n + 1; j <= n + m; j++)
        {
            if (checkFlow({i, j}) == 0 && adjList[i][j].s != 0)
                cout << i << ' ' << j - n << '\n';
        }
    }
    cout << adjList[0][2].f <<  ' ' << adjList[0][2].s << '\n';
    */
}