Cod sursa(job #2207349)

Utilizator MaligMamaliga cu smantana Malig Data 25 mai 2018 15:47:48
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.92 kb
#include <bits/stdc++.h>

using namespace std;

#if 1
    #define pv(x) cout<<#x<<" = "<<(x)<<"; ";cout.flush()
    #define pn cout<<endl
#else
    #define pv(x)
    #define pn
#endif

#ifdef INFOARENA
    ifstream in("maxflow.in");
    ofstream out("maxflow.out");
#else
    #define in cin
    #define out cout
#endif

using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
#define pb push_back
#define mp make_pair
const int NMax = 1e4 + 5;
const ll inf_ll = 1e18 + 5;
const int inf_int = 1e9 + 5;
const int mod = 100003;
using zint = int;

unordered_map<int,int> cap[NMax];
int prv[NMax];
bool vis[NMax];
vector<int> adj[NMax];

bool bfs(int source, int dest) {
    memset(vis, 0, sizeof(vis));
    memset(prv, 0, sizeof(prv));

    queue<int> Q;
    Q.push(source);
    while (Q.size()) {
        int curr = Q.front(); Q.pop();
        // pv(curr); pn;

        if (curr == dest) {
            return true;
        }

        for (int nxt : adj[curr]) {
            if (prv[nxt] || !cap[curr][nxt]) {
                continue;
            }

            prv[nxt] = curr;
            Q.push(nxt);
        }
    }

    return false;
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(0);

    int N, M, E;
    in >> N >> M >> E;

    for (int i = 1;i <= E; ++i) {
        int x,y;
        in >> x >> y;
        y += N;

        // out << x << ' ' << y << '\n';

        cap[x][y] += 1;
        adj[x].pb(y);
        adj[y].pb(x);
    }

    for (int i = 1;i <= N; ++i) {
        cap[N+M+1][i] += 1;
        adj[N+M+1].pb(i);
        adj[i].pb(N+M+1);
    }

    for (int i = M+1; i <= N+M; ++i) {
        cap[i][N+M+2] += 1;
        adj[N+M+2].pb(i);
        adj[i].pb(N+M+2);        
    }
    int source = N + M + 1;
    int dest = N + M + 2;

    int maxFlow = 0;
    while (bfs(source, dest)) {
        // pv("da"); pn;
        for (int i = N+1;i <= N+M; ++i) {
            if (cap[i][dest] == 0 || !prv[i]) {
                continue;
            }

            prv[dest] = i;
            
            int node = dest;
            int minFlow = inf_int;
            while (node != source) {
                // pv(node); pn;
                minFlow = min(minFlow, cap[prv[node]][node]);
                node = prv[node];
            }

            node = dest;
            while (node != source) {
                // pv(node); pn;
                cap[prv[node]][node] -= minFlow;
                cap[node][prv[node]] += minFlow;
                node = prv[node];
            }

            maxFlow += minFlow;
        }
    }

    out << maxFlow << '\n';

    // for (int i = 1; i <= N; ++i) {
    //     for (auto it : cap[i]) {
    //         if (it.second == 0) {
    //             continue;
    //         }

    //         out << i << ' ' << it.first << '\n';
    //     }
    // }


    return 0;
}