Cod sursa(job #3337223)

Utilizator ioan19Buzdugan Ioan-Michael ioan19 Data 27 ianuarie 2026 02:27:15
Problema Cuplaj maxim in graf bipartit Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.98 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

// Fast I/O folosind un buffer mare
class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;
    char read_ch() {
        if (sp == 4096) {
            fread(buff, 1, 4096, fin);
            sp = 0;
        }
        return buff[sp++];
    }
public:
    InParser(const char* name) {
        fin = fopen(name, "r");
        buff = new char[4096];
        sp = 4096;
    }
    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()));
        n = c - '0';
        while (isdigit(c = read_ch())) n = n * 10 + c - '0';
        return *this;
    }
};

const int NMAX = 10005;
vector<int> g[NMAX];
int mt[NMAX], vis[NMAX], L[NMAX], timer;
int N, M, E;

bool try_kuhn(int v) {
    if (vis[v] == timer) return false;
    vis[v] = timer;
    for (int to : g[v]) {
        if (!mt[to] || try_kuhn(mt[to])) {
            mt[to] = v;
            L[v] = to; // Reținem și perechea nodului din stânga
            return true;
        }
    }
    return false;
}

int main() {
    InParser fin("cuplaj.in");
    fin >> N >> M >> E;

    for (int i = 1; i <= E; i++) {
        int x, y;
        fin >> x >> y;
        g[x].push_back(y);
    }

    // Faza Greedy îmbunătățită
    int sol = 0;
    for (int i = 1; i <= N; i++) {
        for (int to : g[i]) {
            if (!mt[to]) {
                mt[to] = i;
                L[i] = to;
                sol++;
                break;
            }
        }
    }

    // Faza Kuhn
    for (int i = 1; i <= N; i++) {
        if (!L[i]) { // Doar dacă nodul din stânga nu e deja cuplat
            timer++;
            if (try_kuhn(i)) sol++;
        }
    }

    FILE *fout = fopen("cuplaj.out", "w");
    fprintf(fout, "%d\n", sol);
    for (int i = 1; i <= M; i++) {
        if (mt[i]) fprintf(fout, "%d %d\n", mt[i], i);
    }
    fclose(fout);

    return 0;
}