Cod sursa(job #741460)

Utilizator BitOneSAlexandru BitOne Data 26 aprilie 2012 07:12:22
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <queue>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <algorithm>

using namespace std;

const int oo=1<<29;
const int N_MAX=10011;

struct vertex {
    int y, capacity, flux, opusIndex;
    vertex(int _y=-1, int _capacity=0): y(_y), capacity(_capacity), flux(0), opusIndex(-1) {}
};
ofstream out("cuplaj.out");

int f[2*N_MAX];

queue<int> Q;
vector<vertex> G[N_MAX];
vector<vertex>::iterator it, iend;
vector<vertex>::iterator index[N_MAX];

int Dinic(const int& source, const int& sink, const int& N)
{
    int x, y, c, s;

    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].begin(), iend=G[x].end(); it < iend; ++it)
            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].begin(), iend=G[sink].end(), s=c=0; it < iend; ++it, s+=c)
        if(-1 !=f[it->y])
        {
			index[sink]=G[it->y].begin()+it->opusIndex;
            f[sink]=it->y;
            c=oo;
			for(y=sink; y != f[y]; y=f[y])
				if(c > index[y]->capacity-index[y]->flux)
				{
					c=index[y]->capacity-index[y]->flux;
					
				}
			for(y=sink; y != f[y]; y=f[y])
            {
                index[y]->flux+=c;
                G[y][index[y]->opusIndex].flux-=c;
            }
        }
    return s;
}

int main()
{
    int N, M, E, x, y, sink, s;
    ifstream in("cuplaj.in");

    for(in>>N>>M>>E; E; --E)
    {
        in>>x>>y;
        y+=N;
        G[x].push_back(vertex(y, 1));
        G[y].push_back(vertex(x, 0));
        G[x].back().opusIndex=G[y].size()-1;
        G[y].back().opusIndex=G[x].size()-1;
    }
    for(x=1; x <= N; ++x)
    {
        G[0].push_back(vertex(x, 1));
        G[x].push_back(vertex(0, 0));
        G[0].back().opusIndex=G[x].size()-1;
        G[x].back().opusIndex=G[0].size()-1;
    }
    sink=M+N+1;
    for(M=sink-1; x <= M; ++x)
    {
        G[x].push_back(vertex(sink, 1));
        G[sink].push_back(vertex(x, 0));
        G[x].back().opusIndex=G[sink].size()-1;
        G[sink].back().opusIndex=G[x].size()-1;
    }
    for(s=0; (x=Dinic(0, sink, N)); s+=x);
    out<<(s-2)<<'\n';
    for(x=1; x <= N; ++x)
    {
        for(it=G[x].begin(), iend=G[x].end(); it < iend; ++it)
            if(it->flux > 0)
            {
                out<<x<<' '<<(it->y-N)<<'\n';
                break;
            }
    }

    return EXIT_SUCCESS;
}