Cod sursa(job #3141838)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 16 iulie 2023 22:03:14
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.99 kb
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
#include <limits>
using namespace std;

const int INF = numeric_limits<int>::max() / 2;


bool dfs_rec(
    int nod,
    int n,
    int m,
    const vector<vector<int>> &adj,
    vector<int> &leftPair,
    vector<int> &rightPair,
    vector<int> &depth_st)
{
    if (depth_st[nod] == INF)
        return false;

    for (auto v : adj[nod]) {
        int lp = leftPair[v];

        if (lp == 0) {
            leftPair[v] = nod;
            rightPair[nod] = v;
            depth_st[nod] = INF;
            return true;
        }
        else if (depth_st[lp] == depth_st[nod] + 1) {
            bool found = dfs_rec(lp, n, m, adj, leftPair, rightPair, depth_st);
            if (found) {
                leftPair[v] = nod;
                rightPair[nod] = v;
                depth_st[nod] = INF;
                return true;
            }
        }
    }

    return false;
}



bool bfs(
    int n,
    int m,
    const vector<vector<int>> &adj,
    vector<int> &leftPair,
    vector<int> &rightPair)
{
    queue<int> q;
    vector<int> depth_st(n+1, INF);

    for (int i = 1; i <= n; ++i) {
        if (rightPair[i] == 0) {
            q.push(i);
            depth_st[i] = 0;
        }
    }

    int levelFound = -1;

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

        if (levelFound != -1 && depth_st[nod] > levelFound)
            break;

        for (int v : adj[nod]) {
            if (leftPair[v] == 0) {
                if (levelFound == -1)
                    levelFound = depth_st[nod];
            }
            else if ((levelFound == -1 || depth_st[nod] < levelFound)
                && rightPair[nod] != v /* SAU: leftPair[v] != nod */
                /*&& leftPair[v] != 0 -- because of "else if" */
                && depth_st[leftPair[v]] == INF)
            {
                int nodNou = leftPair[v];
                depth_st[nodNou] = depth_st[nod]+1;
                q.push(nodNou);
            }
        }
    }

    for (int i = 1; i <= n; ++i) {
        if (rightPair[i] == 0) {
            bool found = dfs_rec(i, n, m, adj, leftPair, rightPair, depth_st);
            //cout << found << endl;
        }
    }



    return levelFound != -1;
}


int main ()
{
    ifstream fin("cuplaj.in");
    ofstream fout("cuplaj.out");

    int n, m, e;
    fin >> n >> m >> e;

    vector<vector<int>> adj(n+1);

    // leftPair[nod din dreapta] == nod din stanga SAU 0
    vector<int> leftPair(m+1, 0);

    // rightPair[nod din stanga] == nod din dreapta SAU 0
    vector<int> rightPair(n+1, 0);

    for (int i = 0; i < e; ++i) {
        int a, b;
        fin >> a >> b;
        adj[a].push_back(b);
    }

    while(bfs(n, m, adj, leftPair, rightPair))
        ;

    int cuplaj = 0;
    for(int i = 1; i <= n; ++i)
        if (rightPair[i] != 0) ++cuplaj;

    fout << cuplaj << "\n";

    for(int i = 1; i <= n; ++i)
        if (rightPair[i] != 0)
            fout << i << ' ' << rightPair[i] << "\n";

    return 0;
}