Cod sursa(job #3190906)

Utilizator tudorcioc5Cioc Tudor tudorcioc5 Data 8 ianuarie 2024 12:17:40
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.88 kb
// https://www.infoarena.ro/problema/cuplaj

#include <iostream>
#include <vector>
#include <utility>
#include <climits>
#include <deque>
#include <queue>
#include <fstream>
#include <algorithm>

using namespace std;

class Graph
{
private:
    static const int MAX_VERTICES = 1000;
    static const int MAX_EDGES = 5000;

    int noVerticesLeft;
    int noVerticesRight;

    vector<vector<int>> neighbours;
    vector<int> left;
    vector<int> right;

public:
    Graph(const int &noVerticesLeft, const int &noVerticesRight)
        : noVerticesLeft(noVerticesLeft),
          noVerticesRight(noVerticesRight),
          neighbours(noVerticesLeft + noVerticesRight + 1),
          left(noVerticesLeft + 1),
          right(noVerticesRight + 1)
    {
    }

    int getNoVerticesLeft()
    {
        return noVerticesLeft;
    }

    int getNoVerticesRight()
    {
        return noVerticesRight;
    }

    void addNeighbour(const int &vertex, const int &neighbour_to_add)
    {
        neighbours[vertex].push_back(neighbour_to_add);
    }

    int pairup(const int &curr_node, vector<int> &visited)
    {
        if (visited[curr_node])
            return 0;

        visited[curr_node] = 1;

        for (auto neigh : neighbours[curr_node])
            if (!right[neigh])
            {
                left[curr_node] = neigh;
                right[neigh] = curr_node;
                return 1;
            }

        for(auto neigh : neighbours[curr_node])
        if (pairup(right[neigh], visited))
        {
            left[curr_node] = neigh;
            right[neigh] = curr_node;
            return 1;
        }
        return 0;
    }

    void cuplaj(vector<pair<int, int>>& edges)
    {
        int cuplaj = 0;
        vector<int> visited(noVerticesLeft + noVerticesRight + 1);

        bool modified = 1;

        while (modified)
        {
            modified = 0;

            visited = vector<int> (noVerticesLeft + noVerticesRight + 1);

            for (int i=1; i <= noVerticesLeft; i++)
                if (!left[i])
                    if (pairup(i, visited))
                        modified = 1;
        }

        for (int i=1; i <= noVerticesLeft; i++)
            if (left[i] > 0)
                edges.push_back({i, left[i]});
    }
};

int main()
{
    int N, M, noEdges;

    ifstream fin("cuplaj.in");
    fin >> N >> M >> noEdges;
    Graph graph(N, M);

    for (int i = 1; i <= noEdges; i++)
    {
        int left, right;
        fin >> left >> right;

        graph.addNeighbour(left, right);
    }

    fin.close();

    ofstream fout("cuplaj.out");

    vector<pair<int, int>> edges;
    graph.cuplaj(edges);

    fout << edges.size() << "\n";
    for (pair<int, int> edge: edges)
        fout << edge.first << " " << edge.second << "\n";


    fout.close();

    return 0;
}