Cod sursa(job #2967848)

Utilizator N.B.Lnabil. N.B.L Data 20 ianuarie 2023 10:32:04
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.33 kb
//algoritmul lui Hopcroft Karp O(sqrt(VE))
#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <climits>
#include <queue>


#define MAXI INT_MAX
using namespace std;

int n, m, e, a, b;
vector<int> la[20001];
queue<int> q;
int dist[20001];
int stanga[20001], dreapta[20001];

bool bfs() {
    //primul layer de nod uri ii setam distanta cu 0
    for (int i = 1; i <= n; i++)
        if (!dreapta[i]) {
            //daca e liber,il bagam in coada
            q.push(i);
            dist[i] = 0;
        } else//notam distanta cu infinit ca sa fie luat data urmatoare
            dist[i] = MAXI;
    dist[0] = MAXI;
    //q o sa aiba nodurile de stanga
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        //daca nodul nu e 0 si poate aduce un short path catre 0
        if (dist[node] < dist[0])//daca il cuplez pe 0 cu cineva => am gasit cuplaj din lant de lungime minimia
        {
            //parcurgem toti vecinii lui node
            for (auto next: la[node]) {
                if (dist[stanga[next]] == MAXI)//next e cuplat cu stanga[next]
                {
                    dist[stanga[next]] = 1 + dist[node];
                    q.push(stanga[next]);
                }
            }
        }
    }
    return dist[0] != MAXI; //lant
}

//returneaza adevarat daca e un augmenting path incepand cu nodul liber node
bool dfs(int node) {
    if (node != 0) {
        for (auto next: la[node])
            if (1 + dist[node] == dist[stanga[next]] && dfs(stanga[next])) {

                stanga[next] = node;
                dreapta[node] = next;
                return true;
            }
        //nu am gasit path
        dist[node] = MAXI;
        return false;
    }
    return true;
}

int maxmatch() {
    int ans = 0;
    while (bfs()) {
        for (int i = 1; i <= n; i++)
            if (!dreapta[i] && dfs(i))
                ans++;
    }
    return ans;
}

int main() {
    ifstream cin("cuplaj.in");
    ofstream cout("cuplaj.out");
    cin >> n >> m >> e;
    fill(stanga, stanga + 20001, 0);
    fill(dreapta, dreapta + 20001, 0);
    for (int i = 1; i <= e; i++) {
        cin >> a >> b;
        la[a].push_back(b);
    }
    cout << maxmatch() << '\n';
    for (int i = 1; i <= m; i++)
        if (stanga[i])
            cout<< stanga[i] << ' ' << i << '\n';
    return 0;
}