Cod sursa(job #1464239)

Utilizator petru.cehanCehan Petru petru.cehan Data 22 iulie 2015 18:04:51
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <vector>
#include <cstring>
#include <stdio.h>
#include <fstream>

#define INF 10001

using namespace std;

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

vector<int> graph [INF] ;

int n , m ,e ;
bool used[INF] ;//nodurile folosite intr-o iteratie
int cuplajSD[INF] , cuplajDS[INF] ; //cuplajele realizate - in ambele sensuri ( Stanga - Dreapta , Dreapta - Stanga )

int match ( int ind )
{
    if( used[ind] == true )
        return 0 ;//daca a mai fost folosit in interatia curenta, ne intoarcem

    used[ind] = 1 ;// daca nu il folosim acum

    for ( vector < int > :: iterator it = graph[ind].begin() ; it != graph[ind].end() ; it ++ )
        if ( cuplajDS[*it] == 0 ) //incercam mai intai sa-l cuplam cu un nod adiacent liber
        {
            cuplajSD [ind] = *it ;
            cuplajDS [*it] =ind ;

            return 1; //daca reusim, ne intoarcem
        }

    for ( vector < int > :: iterator it = graph[ind].begin() ; it != graph[ind].end() ; it ++ )
        if ( match ( cuplajDS [*it] ) ) //inceram a doua oara sa eliberam un nod adiacent ocupat
        {
            cuplajSD [ind] = *it ;
            cuplajDS [*it] = ind ;

            return 1;//daca reusim sa eliberam un loc, il cuplam cu nodul curent
        }

    return 0 ; //daca nu reusim sa-l cuplam
}

int main()
{
    fin >> n >> m >> e ;

    for ( int i = 0 ; i < e ;++ i )
    {
        int x,y ;
        fin >> x >> y ;
        graph[x].push_back(y);
    }

    int sw = 1 ;
    while( sw ) //cat timp s-a facut o cuplare in iteratia anterioara => este posibil sa mai putem cupla ceva
    {
        sw = 0 ;
        memset ( used , false , sizeof(used) ) ; //resetam used

        for ( int i = 1 ;i <= n ;++ i )
            if ( !cuplajSD [i] ) sw += match(i) ;//daca nodul curent nu e cuplat, incercam sa-l cuplam
    }

    int matches = 0 ;
    for ( int i = 1 ; i <= n ; ++ i )
        if ( cuplajSD[i] )
           ++ matches ;//numaram cuplajele

    fout << matches << "\n" ;
    for ( int i = 1 ; i <= n ; ++ i )
            if ( cuplajSD [i] )
                  fout << i << " " << cuplajSD [i] << "\n" ; //scriem cuplajele

    return 0 ;
}