Cod sursa(job #2876841)

Utilizator NuSuntRomanIspir Alexandru NuSuntRoman Data 23 martie 2022 18:12:56
Problema Cuplaj maxim in graf bipartit Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.01 kb
#include <bits/stdc++.h>

using namespace std;

int n, m, E;
vector < int > A[2][10005];
map < pair < int, int >, int > muchii;
int noduri[2][10005];
int g[2][10005];
int d[2][10005], previous[2][10005], f[2][10005];

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

void maxbipmatch() {

    /**
    for (int i = 1; i <= n; ++ i)
        noduri[0][i] = 0;

    for (int i = 1; i <= m; ++ i)
        noduri[1][i] = 0;
    **/

    for (int i = 1; i <= n; ++ i) {
        for (int j = 0; j < A[0][i].size(); ++ j) {
            int u = A[0][i][j];

            if (!noduri[1][u]) {
                muchii[{i, u}] = 1;
                noduri[0][i] = noduri[1][u] = 1;
                break;
            }
        }
    }

    bool OK;

    do {
        queue < pair < int, int > > Q;

        for (int i = 1; i <= n; ++ i)
            f[0][i] = g[0][i] = 0;

        for (int i = 1; i <= m; ++ i)
            f[1][i] = g[1][i] = 0;

        for (int i = 1; i <= n; ++ i) {
            if (!noduri[0][i]) {
                Q.push({0, i});
                f[0][i] = 1;
                previous[0][i] = d[0][i] = 0;
            }
        }

        OK = false;
        int dist = (1 << 30);
        vector < int > ans;

        while (!Q.empty()) {
            int dep = Q.front().first, u = Q.front().second;

            if (!noduri[dep][u] && dep > 0) {
                dist = d[dep][u];
                OK = true;
            }

            if (dist == d[dep][u] && !noduri[dep][u] && dep == 1)
                ans.push_back(u);
            else
                if (dist > d[dep][u]) {
                    for (int i = 0; i < A[dep][u].size(); ++ i) {
                        int v = A[dep][u][i];

                        if (!f[!dep][v]) {
                            f[!dep][v] = 1;
                            d[!dep][v] = 1 + d[dep][u];
                            previous[!dep][v] = u;
                            Q.push({!dep, v});
                        }
                    }
                }

            Q.pop();
        }

        for (int i = 0; i < ans.size(); ++ i) {
            int c = 1, t = ans[i];
            bool OKK = true;

            while (previous[c][t] != 0) {
                OKK = min(OKK, (g[c][t] == 0));
                t = previous[c][t];
                c = !c;
            }

            if (OKK == true) {
                c = 1, t = ans[i];
                while (previous[c][t] != 0) {
                    if (c == 1)
                        muchii[{previous[c][t], t}] = 1;
                    else
                        muchii[{t, previous[c][t]}] = 0;

                    t = previous[c][t];
                    c = !c;
                }

                noduri[1][ans[i]] = noduri[0][t] = 1;
            }
        }

        /**

        int cuplaj = 0;

        for (map < pair < int, int >, int > :: iterator it = muchii.begin(); it != muchii.end(); ++ it)
            if ((it -> second) > 0)
                ++ cuplaj;

        cout << cuplaj << "\n";

        for (map < pair < int, int >, int > :: iterator it = muchii.begin(); it != muchii.end(); ++ it)
            if ((it -> second) > 0)
                cout << (it -> first).first << " " << (it -> first).second << "\n";

        cout << "\n";

        **/

    } while (OK == true);

    int cuplaj = 0;

    for (map < pair < int, int >, int > :: iterator it = muchii.begin(); it != muchii.end(); ++ it)
        if ((it -> second) > 0)
            ++ cuplaj;

    fout << cuplaj << "\n";

    for (map < pair < int, int >, int > :: iterator it = muchii.begin(); it != muchii.end(); ++ it)
        if ((it -> second) > 0)
            fout << (it -> first).first << " " << (it -> first).second << "\n";

    return;
}

int main() {
    fin >> n >> m >> E;

    for (int i = 1, u, v; i <= E; ++ i) {
        fin >> u >> v;

        A[0][u].push_back(v);
        A[1][v].push_back(u);
    }

    maxbipmatch();

    return 0;
}