Cod sursa(job #2821477)

Utilizator Angel2IonitaAngel Ionita Angel2Ionita Data 22 decembrie 2021 17:10:37
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.06 kb
#include <iostream>
#include <fstream>
#include <climits>
#include <list>
#include <vector>
#include <queue>

using namespace std;

const int INF = INT_MAX;
ifstream f("cuplaj.in");
ofstream o("cuplaj.out");

class Graph
{

    int size, size2;
    vector<vector<int>> adjList;
    bool hk_bfs(vector<int> &toRight, vector<int> &toLeft, vector<int> &dist)
    {
        queue<int> q;
        for (int u = 1; u <= size; u++)
        {
            if (toRight[u] == 0)
            {

                dist[u] = 0;
                q.push(u);
            }
            else
                dist[u] = INF;
        }
        dist[0] = INF;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            if (dist[u] < dist[0])
            {
                for (auto i:adjList[u])
                {
                    int v = i;
                    if (dist[toLeft[v]] == INF)
                    {
                        dist[toLeft[v]] = dist[u] + 1;
                        q.push(toLeft[v]);
                    }
                }
            }
        }
        return (dist[0] != INF);
    }

    bool hk_dfs(int u, vector<int> &toRight, vector<int> &toLeft, vector<int> &dist)
    {
        if (u != 0)
        {
            for (auto i : adjList[u])
            {
                int v = i;
                if (dist[toLeft[v]] == dist[u] + 1)
                {
                    if (hk_dfs(toLeft[v], toRight, toLeft, dist) == true)
                    {
                        toLeft[v] = u;
                        toRight[u] = v;

                        return true;
                    }
                }
            }
            dist[u] = INF;
            return false;
        }
        return true;
    }
public:
    Graph(int size_left, int size_right)
    {
        size = size_left;
        size2 = size_right;
        adjList.resize(size_left + 1);
    }
    void addEdge(int start, int end)
    {
        adjList[start].push_back(end);
    }
    pair<int, vector<int>> HopcroftKarp(vector<int> &toRight, vector<int> &toLeft, vector<int> &dist)
    {
        dist.resize(size + 1);
        for (int u = 0; u <= size; u++)
            toRight.push_back(0);
        for (int v = 0; v <= size2; v++)
            toLeft.push_back(0);

        int count = 0;

        while (hk_bfs(toRight, toLeft, dist))
        {
            for (int u = 1; u <= size; u++)
                if (toRight[u] == 0 && hk_dfs(u, toRight, toLeft, dist))
                    count++;
        }
        return {count, toRight};
    }
};

int main()
{
    int N, M, E;
    f >> N >> M >> E;
    Graph g(N, M);
    int x, y;
    for (int i = 1; i <= E; i++)
    {
        f >> x >> y;
        g.addEdge(x, y);
    }
    vector<int> toRight, toLeft, dist;
    pair<int, vector<int>> res = g.HopcroftKarp(toRight, toLeft, dist);
    o << res.first << endl;
    for (int i = 1; i <= N; i++)
        if (res.second[i])
            o << i << " " << res.second[i] << endl;

    return 0;
}