Cod sursa(job #514870)

Utilizator gabipurcaruGabi Purcaru gabipurcaru Data 19 decembrie 2010 19:41:13
Problema Cuplaj maxim in graf bipartit Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
// infoarena: problema/cuplaj //
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <map>
using namespace std;

const int MAXN = 2010;

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

vector<int> g[MAXN];
int t[MAXN],i,j,n,m,a,b,s,d,e,r,nod,flux;
map<int,int> c[MAXN], f[MAXN];

int bf()
{
    deque<int> q;
    int nod;
    memset(t, 0, sizeof(t));
    q.push_back(s);

    while(!q.empty())
    {
        nod = q.front();
        q.pop_front();

        for(i=0; i<g[nod].size(); ++i)
            if(!t[g[nod][i]] && c[nod][g[nod][i]] > f[nod][g[nod][i]])
            {
                t[g[nod][i]] = nod, q.push_back(g[nod][i]);

                if(g[nod][i] == d)
                {
                    return 1;
                }
            }
    }
    return 0;
}

int main()
{
    in>>n>>m>>e;
    s = 0;
    d = n+m+1;

    for(i=1; i<=e; i++)
    {
        in>>a>>b;
        g[a].push_back(n+b);
        g[n+b].push_back(a);
        c[a][n+b] = 1;
        c[s][a]   = 1;
        c[n+b][d] = 1;
    }

    for(i=1; i<=n; i++)
        g[s].push_back(i), c[s][i] = 1;
    for(i=1; i<=m; i++)
        g[n+i].push_back(d), c[n+i][d] = 1;

    while(bf())
    {
        r = 1<<30;
        nod = d;
        while(nod != s)
            r = min(r, c[t[nod]][nod] - f[t[nod]][nod]), nod = t[nod];

        f[t[d]][d] ++;
        f[d][t[d]] --;
        nod = t[d];
        while(nod != s)
        {
            f[t[nod]][nod] ++;
            f[nod][t[nod]] --;
            nod = t[nod];
        }
        flux ++;
    }

    out<<flux;

    return 0;
}