Cod sursa(job #741923)

Utilizator BitOneSAlexandru BitOne Data 27 aprilie 2012 15:45:49
Problema Cuplaj maxim in graf bipartit Scor 8
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <queue>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <iterator>
#include <algorithm>

using namespace std;

const int N_MAX=10011;
const int DN_MAX=(N_MAX<<1)|1;

struct vertex {

    int y, capacity, flux;
    vertex *next, *reverseEdge;

    vertex(int _y=-1, int _capacity=-1) : y(_y), capacity(_capacity), flux(0), next(NULL), reverseEdge(NULL) {}
} *G[DN_MAX], *index[DN_MAX];
vertex *it;
const vertex *iend=NULL;

queue<int> Q;
int f[DN_MAX];

inline int _min(int x, int y) {return x <= y ? x : y;}
void Add(int x, int y)
{
    vertex *p, *q;
    p=new vertex;      q=new vertex;
    p->y=y;            q->y=x;
    p->capacity=1;     q->capacity=0;
    p->reverseEdge=q;  q->reverseEdge=p;
    p->next=G[x];      q->next=G[y];
    G[x]=p;            G[y]=q;
}
int getPathAug(const int& source, const int& sink)
{
    int x, y, s=0, c=0;

    fill(f, f+sink+1, -1);
    f[source]=0;
    for(Q.push(source); !Q.empty(); Q.pop())
    {
        x=Q.front();
        if(sink == x) continue;
        for(it=G[x]; it != iend; it=it->next)
            if(-1 == f[it->y] && it->capacity > it->flux)
            {
                f[it->y]=x;
                index[it->y]=it;
                Q.push(it->y);
            }
    }
    if(-1 == f[sink])
      return 0;
    for(it=G[sink]; iend != it; it=it->next, s+=c)
        if(-1 != f[it->y])
        {
            f[sink]=it->y;
            index[sink]=it->reverseEdge;
            for(y=sink, c=2; y != f[y]; y=f[y])
                c=_min(c, index[y]->capacity - index[y]->flux);
            for(y=sink; y != f[y]; y=f[y])
            {
                index[y]->flux+=c;
                index[y]->reverseEdge->flux-=c;
            }
        }
    return s;
}
int main()
{
    int N, M, E, sink, s=0, x, y;
    ifstream in("cuplaj.in");
    ofstream out("cuplaj.out");

    for(in>>N>>M>>E; E; --E)
    {
        in>>x>>y;
        Add(x, y+N);
    }
    for(x=1; x <= N; ++x)
        Add(0, x);
    for(sink=N+M+1; x < sink; ++x)
        Add(x, sink);
    for(s=0; (x=getPathAug(0, sink)); s+=x);
    out<<'\n';
    for(x=1, s=0; x <= N; ++x)
    {
        for(it=G[x]; iend != it; it=it->next)
            if(it->flux > 0)
            {
                out<<x<<' '<<(it->y-N)<<'\n';
                ++s;
                break;
            }
    }
    out.seekp(0, ios::beg);
    out<<s;

    return EXIT_SUCCESS;
}