Cod sursa(job #2901063)

Utilizator raulandreipopRaul-Andrei Pop raulandreipop Data 12 mai 2022 20:20:12
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.44 kb
#include <iostream>
#include <vector>
#include <queue>
#include <list>

using namespace std;
int inf = INT_MAX;

class Bipart {
    int m, n;

    list<int> *adj;
    int *pu, *pv, *dist;

    public:
    Bipart(int m, int n);
    void addEdge(int u, int v);

    bool bfs(), dfs(int u);
    void hopcroftKarp();
};

Bipart::Bipart(int m, int n)
{
    this->m = m;
    this->n = n;
    adj = new list<int>[m+1];
}

void Bipart::addEdge(int u, int v)
{
    adj[u].push_back(v);
}

void Bipart::hopcroftKarp()
{
    pu = new int[m+1];
    pv = new int[n+1];
    dist = new int[m+1];

    for (int u = 0; u <= m; u++)
        pu[u] = 0;
    for (int v = 0; v <= n; v++)
        pv[v] = 0;
    
    int result = 0;

    while (bfs())
    {
        for (int i = 1; i <= m; i++)
        {
            if (pu[i] == 0 && dfs(i)) result++;
        }
    }

    cout << result << '\n';

    for (int i = 1; i <= m; i++)
    {
        if (pu[i] > 0) cout << i << ' ' << pu[i] << '\n';
    }
}

bool Bipart::bfs()
{
    queue<int> q;

    for (int i = 1; i <= m; i++)
    {
        
        if (pu[i] == 0){
            dist[i] = 0;
            q.push(i);
        }
        else dist[i] = inf;
        
    }

    dist[0] = inf;

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

        if (dist[nod] >= dist[0]) continue;

        list<int>::iterator it;
        for (it = adj[nod].begin(); it != adj[nod].end(); ++it)
        {
            int v = *it;
            
            if (dist[pv[v]] == inf)
            {
                dist[pv[v]] = dist[nod] + 1;
                q.push(pv[v]);
            }
        }
    }

    return (dist[0] != inf);
}

bool Bipart::dfs(int nod)
{
    if (nod == 0) return 1;
    list<int>::iterator it;
    for (it = adj[nod].begin(); it != adj[nod].end(); it++)
    {
        int v = *it;
        if (dist[pv[v]] == dist[nod] + 1)
        {
            if (dfs(pv[v]) == 1)
            {
                pv[v] = nod;
                pu[nod] = v;
                return 1;
            }
        }
    }
    return 0;
}


int main ()
{
    freopen("cuplaj.in", "r", stdin);
    freopen("cuplaj.out", "w", stdout);

    int m, n, e;
    cin >> m >> n >> e;
    Bipart bip(m, n);
    for (int i = 1; i <= e; i++)
    {
        int x, y; cin >> x >> y;
        bip.addEdge(x, y);
    }
    bip.hopcroftKarp();

}