Cod sursa(job #448061)

Utilizator alexandru92alexandru alexandru92 Data 2 mai 2010 16:10:26
Problema Cuplaj maxim in graf bipartit Scor 16
Compilator cpp Status done
Runda Arhiva educationala Marime 2.01 kb
/* 
 * File:   main.cpp
 * Author: virtualdemon
 *
 * Created on May 1, 2010, 5:21 PM
 */
#include <queue>
#include <cstdlib>
#include <fstream>
#include <algorithm>
#define Nmax 20011

/*
 * 
 */
using namespace std;
struct pr
{
    int y, c;
    pr* next, *rit;
} *G[Nmax], *p[Nmax];
int f[Nmax];
int N, M, sink=20005, source;
inline void add( int x, int y )
{
    pr* q=new pr;
    q->y=y; q->c=1; q->next=NULL;
    q->next=G[x];
    G[x]=q;
    pr* qq=new pr;
    qq->y=x; qq->c=0; qq->next=NULL;
    qq->next=G[y];
    G[y]=qq;
    G[x]->rit=G[y];
    G[y]->rit=G[x];
}
inline int find_path( void )
{
    int x;
    pr* q;
    queue< int > Q;
    fill( f+1, f+N+M+1, -1 );
    f[sink]=-1;
    f[source]=-2;
    for( Q.push(source); -1 == f[sink] && !Q.empty(); )
    {
        x=Q.front(); Q.pop();
        for( q=G[x]; q; q=q->next )
            if( q->c > 0 && -1 == f[q->y] )
            {
                f[q->y]=x;
                p[q->y]=q;
                Q.push(q->y);
            }
    }
    if( -1 == f[sink] )
        return 0;
    for( x=sink; -2 != f[x]; x=f[x] )
        --p[x]->c, ++p[x]->rit->c;
    return 1;
}
inline int MaxFlow( void )
{
    int s;
    for( s=0; find_path(); ++s );
    return s;
}
int main( void )
{
    pr* q;
    int E, x, y;
    ifstream in( "cuplaj.in" );
    for( in>>N>>M>>E; E; --E )
    {
        in>>x>>y;
        add( x, y+N+1 );
    }
    for( x=1; x <= N; ++x )
        if( G[x] )
            add( source, x );
    for( y=1; y <= M; ++y )
        if( G[y+N+1] )
            add( y+N+1, sink );
     ofstream out( "cuplaj.out" ); /*
     for( x=1; x <= N; ++x )
     {
         out<<x<<":\n";
         for( q=G[x]; q; q=q->next )
             out<<q->y<<' '<<q->c<<' '<<q->rit->y<<' '<<q->rit->c<<'\n';
         out<<'\n';
     } */
     out<<'\n'<<MaxFlow()+1<<'\n';
     for( x=1; x <= N; ++x )
     {
         for( q=G[x]; q; q=q->next )
             if( q->c && q->y )
             {
                 out<<x<<' '<<(q->y-N-1)<<'\n';
                 break;
             }
     }
     return EXIT_SUCCESS;
}