Cod sursa(job #2896731)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 30 aprilie 2022 13:01:07
Problema Cuplaj maxim in graf bipartit Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.84 kb
#include <fstream>
#include <queue>
#include <vector>
#include <limits>
using namespace std;

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

bool bfs(
    int n,
    int m,
    const vector<vector<int>> &adj,
    vector<int> &leftPair,
    vector<int> &rightPair)
{
    bool result = false;

    for (int start = 1; start <= n; ++start) {
        // fiecare nod liber din stanga
        if (rightPair[start] == 0) {

            queue<int> q;
            vector<int> parent_st(n+1, 0);
            vector<int> parent_dr(m+1, 0);

            q.push(start);
            parent_st[start] = -1;

            int found = 0;

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

                for (int v : adj[nod]) {
                    if (leftPair[v] == 0) {
                        parent_dr[v] = nod;
                        found = v;
                        break;
                    }
                    else if (parent_dr[v] == 0
                        && rightPair[nod] != v /* SAU: leftPair[v] != nod */
                        /*&& leftPair[v] != 0*/
                        && parent_st[leftPair[v]] == 0)
                    {
                        int nodNou = leftPair[v];
                        parent_st[nodNou] = v;
                        parent_dr[v] = nod;
                        q.push(nodNou);
                    }
                }
            }


            if (found != 0) {
                // -- parent_st[parent_dr[v]] -- parent_dr[v] --- v
                //                                   == start?

                int nodr = found;
                while (true) {
                    int nods = parent_dr[nodr];

                    leftPair[nodr] = nods;
                    rightPair[nods] = nodr;

                    if (nods == start) {
                       break;
                    }
                    else {
                        int parent = parent_st[nods];
                        nodr = parent;
                    }
                }

                result = true;
            }
        }
    }

    return result;
}


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;
}