Cod sursa(job #3031317)

Utilizator Cezar211Popoveniuc Cezar Cezar211 Data 19 martie 2023 14:40:55
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.03 kb
#include <bits/stdc++.h>

#define NMAX 200005
using namespace std;

void fast() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}

struct BipartiteMatching {
    int n, k;
    int totalSize;
    vector<int> ma;
    vector<bool> viz;
    vector<vector<int>> v;

    BipartiteMatching(int n, int k) : n(n), k(k) {
        totalSize = n + k + 3;
        v.resize(totalSize);
        viz.resize(totalSize);
        ma.resize(totalSize);
    }

    void addEdge(int x, int y) {
        v[x].push_back(y + n);
        v[y + n].push_back(x);
    }

    bool dfsMatching(int node) {
        if (viz[node])
            return false;
        viz[node] = true;
        for (auto it: v[node])
            if (!ma[it] || dfsMatching(ma[it])) {
                ma[node] = it, ma[it] = node;
                return true;
            }
        return false;
    }

    void doMatching() {
        fill(ma.begin(), ma.end(), 0);
        bool ok = true;
        while (ok) {
            ok = false;
            fill(viz.begin(), viz.end(), false);
            for (int i = 1; i <= n; i++)
                if (!ma[i] && !viz[i] && dfsMatching(i))
                    ok = true;
        }
    }

    int getMatchingResult() {
        int cntMatched = 0;
        for (int i = 1; i <= n; i++)
            if (ma[i])
                cntMatched++;
        return cntMatched;
    }

    vector<pair<int, int>> getMatchedPairs() {
        vector<pair<int, int>> pairs;
        for (int i = 1; i <= n; i++)
            if (ma[i])
                pairs.emplace_back(i, ma[i] - n);
        return pairs;
    }

    void dfsVertexCover(int node) {
        viz[node] = true;
        for (auto it: v[node])
            if (!viz[it]) {
                if (!ma[it]) {
                    cout << "WTF";

                }
                assert(ma[it]);
                viz[it] = true;
                dfsVertexCover(ma[it]);
            }
    }

    // get any MVC
    vector<int> getMinVertexCover() {
        fill(viz.begin(), viz.end(), false);
        for (int i = 1; i <= n; i++)
            if (!ma[i] && !viz[i])
                dfsVertexCover(i);
        vector<int> ans;
        ans.reserve(getMatchingResult());
        for (int i = n + 1; i <= n + k; i++)
            if (viz[i])
                ans.push_back(i);
        for (int i = 1; i <= n; i++)
            if (!viz[i])
                ans.push_back(i);
        return ans;
    }
};


int N, M, K;
BipartiteMatching *bipartiteMatching;

void read() {
    ifstream fin("cuplaj.in");
    fin >> N >> M >> K;
    bipartiteMatching = new BipartiteMatching(N, M);
    for (int i = 1; i <= K; i++) {
        int x, y;
        fin >> x >> y;
        bipartiteMatching->addEdge(x, y);
    }
}

void solve() {
    bipartiteMatching->doMatching();
    auto matchedPairs = bipartiteMatching->getMatchedPairs();
    ofstream fout("cuplaj.out");
    fout << matchedPairs.size() << '\n';
    for (auto it: matchedPairs)
        fout << it.first << ' ' << it.second << '\n';
}

int main() {
    fast();
    read();
    solve();

    return 0;
}