Cod sursa(job #2877822)

Utilizator NuSuntRomanIspir Alexandru NuSuntRoman Data 25 martie 2022 13:39:29
Problema Cuplaj maxim in graf bipartit Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.99 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");

bool DFS(int c, int t) {
    if (d[c][t] == 0) {
        g[c][t] = 1;
        noduri[c][t] = 1;
        return 1;
    }
    else {
        g[c][t] = 1;

        for (int i = 0; i < A[c][t].size(); ++ i) {
            int u = A[c][t][i];

            if (!g[!c][u] && d[c][t] == 1 + d[!c][u] && DFS(!c, u)) {
                if (c == 0)
                    muchii[{t, u}] = 1 - muchii[{t, u}];
                else
                    muchii[{u, t}] = 1 - muchii[{u, t}];

                return 1;
            }
        }

        return 0;
    }
}

void maxbipmatch() {

    /**
    for (int i = 1; i <= n; ++ i)
        noduri[0][i] = 0;
{1}
    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], r = DFS(c, t);
            noduri[c][t] = 1;
        }

        /**
{1}
        int cuplaj = 0;
{1}
        for (map < pair < int, int >, int > :: iterator it = muchii.begin(); it != muchii.end(); ++ it)
            if ((it -> second) > 0)
                ++ cuplaj;
{1}
        cout << cuplaj << "\n";
{1}
        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";
{1}
        cout << "\n";
{1}
        **/

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