Cod sursa(job #657973)

Utilizator slycerdan dragomir slycer Data 7 ianuarie 2012 18:16:00
Problema Cuplaj maxim in graf bipartit Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.79 kb
/* 
 * File:   Cuplajmaximingrafbipartit.cpp
 * Author: slycer
 *
 * Created on January 7, 2012, 5:19 PM
 */

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

class Muchie{
public:
    int j,value; 
    Muchie *frate; 
    Muchie( int j, int value, Muchie *frate ){
        this->j = j; 
        this->value = value; 
        this->frate = frate; 
    }
};

class Graf{
public:
    int n; 
    vector<Muchie*> *g; 
    Muchie ** back; 
    bool *marcat; 
    bool *bfs; 
    int a,b;
    Graf( int n, int a, int b){
        this->n = n; 
        this->a = a;
        this->b = b; 
        g = new vector<Muchie*>[n+1];
        back = new Muchie*[n+1]; 
        this->marcat = new bool[n+1]; 
        this->bfs = new bool[n+1]; 
        for ( int i=0; i<=n; i++ ){
            marcat[i]= false; 
        }
    }
    
    void add( int a, int b ){
        Muchie *front = new Muchie(b,1,NULL);
        Muchie *back = new Muchie(a,0,front);
        front->frate = back; 
        
        g[a].push_back( front ); 
        g[b].push_back( back ); 
    }
    
    int feast(){
        int pathFound = 0; 
        for ( int i=0; i<=n; i++){
            bfs[i] = false; 
            back[i] = NULL; 
        }
        vector<int> q;
        for ( int i=1; i<=a; i++ ){
            if ( !marcat[i] ){
                q.push_back( i );
                bfs[i] = true; 
            }
        }
        
        while ( q.size() > 0 ){
            int current = q.back();
            q.pop_back(); 
            for ( int i=0; i<g[current].size(); i++){
                Muchie * aux = g[current][i];
                if ( !bfs[aux->j] && aux->value > 0 ){
                    bfs[aux->j]=true; 
                    back[aux->j] = aux->frate; 
                    if ( aux->j > a &&  marcat[aux->j]==false ){
                        
                    } else {
                        q.push_back( aux->j );
                    }
                }
            }
        }
        
        for ( int i=a+1; i<=n; i++ ){
            if ( bfs[i] == true && marcat[i] == false ){
                bool ok = true; 
                Muchie *current = back[i]; 
                while ( current != NULL ){
                    if ( current->value == 1 ){
                        ok = false; 
                    }
                    if ( back[current->j] == NULL && marcat[current->j]==true ){
                        ok = false;
                    }
                    current = back[ current->j ];
                }
                
                if ( ok ){
                    pathFound ++; 
                    marcat[i] = true; 
                    current = back[i];
                   // cout << "\n\n" << i << endl; 
                    while ( current != NULL ){
                     //   cout <<  current->j << "\n";
                        current->value = 1; 
                        current->frate->value = 0; 
                        marcat[current->j] = true; 
                        current = back[current->j]; 
                    }
                }
            }
        }
       return  pathFound;
    }
};
int main(int argc, char** argv) {

    ifstream input("cuplaj.in");
    ofstream output("cuplaj.out");
    int a,b,muchii; 
    input >> a >> b >> muchii; 
    Graf g(a+b,a,b);
    for ( int i=0; i<muchii; i++ ){
        int i,j; 
        input >>i >> j; 
        j = j + a; 
      //  cout << i << " " << j << "\n";
        g.add(i,j); 
    }
    int sol=0,aux=0; 
    while ( ( aux = g.feast() ) >0 ){
        sol+=aux; 
    }
    
    output << sol << "\n";
    for ( int i=1; i<=a; i++ ){
        for ( int j=0; j<g.g[i].size(); j++){
            Muchie *aux = g.g[i][j];
            if ( aux->value == 0 ){
                output << i << " " << aux->j -a << "\n";
            }
        }
    }
    
    return 0;
}