Cod sursa(job #2444548)

Utilizator alexoloieriAlexandru Oloieri alexoloieri Data 31 iulie 2019 18:07:28
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.1 kb
#include <bits/stdc++.h>
using namespace std;

class maximumBipartiteMatching
{
private:
#define uint unsigned int
#define pb push_back
#define mkp std::make_pair
#define MAX_BIPARTITE_MATCHING_CHECK_CREATED(ret) if(!created) return ret
    uint *lft, *rgh;
    bool *visited;
    std::vector<uint> *graph;
    uint n, m;
    bool created;
    bool cup(uint node)
    {
        if (visited[node]) return false;
        visited[node] = true;
        for (uint i=0; i<graph[node].size(); ++i)
        {
            if (rgh[graph[node][i]]) continue;
            lft[node] = graph[node][i];
            rgh[graph[node][i]] = node;
            return true;
        }
        for (uint i=0; i<graph[node].size(); ++i)
            if (cup(right[graph[node][i]]))
            {
                lft[node] = graph[node][i];
                rgh[graph[node][i]] = node;
                return true;
            }
        return false;
    }
public:
    maximumBipartiteMatching():
        lft(nullptr), rgh(nullptr), graph(nullptr), created(false), visited(nullptr) {}
    bool create(uint szLeft, uint szRight)
    {
        if (created) return false;
        lft = new uint[szLeft + 1];
        if (lft == nullptr) return false;
        rgh = new uint[szRight + 1];
        if (rgh == nullptr)
        {
            delete[] lft;
            return false;
        }
        visited = new bool[szLeft + 1];
        if (visited == nullptr)
        {
            delete[] lft;
            delete[] rgh;
            return false;
        }
        graph = new std::vector<uint>[szLeft + 1];
        n = szLeft + 1;
        m = szRight + 1;
        created = true;
        return true;
    }
    bool addEdge(uint x, uint y)
    {
        MAX_BIPARTITE_MATCHING_CHECK_CREATED(false);
        if (x >= n || y >= m) return false;
        graph[x].pb(y);
        return true;
    }
    bool computeMaxCoupling(std::vector<std::pair<uint,uint>> &ans)
    {
        MAX_BIPARTITE_MATCHING_CHECK_CREATED(false);
        for (uint i=0;i<n;++i)
            lft[i] = 0;
        for (uint i=0;i<m;++i)
            rgh[i] = 0;
        bool ok = true;
        ans.clear();
        while (ok)
        {
            ok = false;
            for (uint i=0;i<n;++i)
                visited[i] = 0;
            for (uint i=1;i<n;++i)
                if (!visited[i] && !lft[i])
                    if (cup(i))
                        ok = true;
        }
        for (uint i=1;i<n;++i)
            if (lft[i])
                ans.pb(mkp(i,lft[i]));
        return true;
    }
};

int main()
{
    freopen("cuplaj.in","r",stdin);
    freopen("cuplaj.out","w",stdout);
    int n, m, cnt, x, y;
    maximumBipartiteMatching cuplaj;
    scanf("%d %d %d",&n,&m,&cnt);
    cuplaj.create(n, m);
    for (int i=1;i<=cnt;++i)
    {
        scanf("%d %d",&x,&y);
        cuplaj.addEdge(x, y);
    }
    vector<pair<unsigned int, unsigned int>>ans;
    cuplaj.computeMaxCoupling(ans);
    printf("%d\n", ans.size());
    for (auto x:ans)
        printf("%d %d\n", x.first, x.second);
    return 0;
}