Cod sursa(job #1951483)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 3 aprilie 2017 17:27:13
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
using pii = pair<int, int>;
#define INF 2000000000
#define NMAX 10002
#define MMAX 10002

struct edge
{
    int u, f, c;
    edge(int _u = 0, int _f = 0, int _c = 0) : u(_u), f(_f), c(_c) {}
};

int n, m, S, T;
vector<edge> edges;
vector<int> adj[NMAX + MMAX], dag[NMAX + MMAX];
bool used[NMAX + MMAX];
queue<int> Q;

void addEdge(int a, int b, int cap)
{
    adj[a].push_back(edges.size());
    edges.emplace_back(b, 0, cap);

    adj[b].push_back(edges.size());
    edges.emplace_back(a, 0, 0);
}

bool bfs(int v)
{
    while(!Q.empty()) Q.pop();
    memset(used, 0, sizeof used);
    for(int i = 0; i <= n + m + 1; ++i) dag[i].clear();

    for(Q.push(v); !Q.empty(); Q.pop())
    {
        v = Q.front();

        if(used[v]) continue;
        used[v] = true;
        if(v == T) continue;
        
        for(auto id : adj[v])
        {
            if(edges[id].f >= edges[id].c) continue;
            if(!used[edges[id].u])
                dag[v].push_back(id),
                Q.push(edges[id].u);
        }
    }

    return used[T];
}

int increaseFlow(int v, int maxF)
{
    if(maxF <= 0) return 0;
    if(v == T) return maxF;

    int sum = 0, f;
    edge e;

    for(auto id : dag[v])
    {
        e = edges[id];
        f = increaseFlow(e.u, min(e.c - e.f, maxF - sum));
        sum += f;

        edges[id].f += f;
        edges[id ^ 1].f -= f;

        if(sum >= maxF) return sum;
    }

    return sum;
}

int main()
{
    int i, e, a, b, cmax;
    fin >> n >> m >> e;
    S = 0; T = n + m + 1;
     
    for(; e; --e) fin >> a >> b, addEdge(a, b + n, 1);
    for(i = 1; i <= n; ++i) addEdge(S, i, 1);
    for(i = 1; i <= m; ++i) addEdge(i + n, T, 1);
    
    cmax = 0;
    while(bfs(S))
        cmax += increaseFlow(S, INF);
     
    fout << cmax << '\n';
     
    for(i = 1; i <= n; ++i)
    {
        for(auto id : adj[i])
            if(edges[id].f > 0)
            {
                fout << i << ' ' << edges[id].u - n << '\n';
            }
    }

    return 0;
}