Cod sursa(job #2894111)

Utilizator Tiberiu02Tiberiu Musat Tiberiu02 Data 27 aprilie 2022 13:02:23
Problema Cuplaj maxim in graf bipartit Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.86 kb
// This program was written on 26.04.2022
// for problem cuplaj
// by Mircea Rebengiuc

#include <stdio.h>
#include <ctype.h>

#include <vector>

#define MAXN 20000
#define NIL -1

std::vector<int> adj[MAXN];
int pair[MAXN];
int viz[MAXN];
int stamp = 1;

bool match( int u ){
  viz[u] = stamp;

  // putem lega usor?
  for( int v : adj[u] ){
    if( pair[v] == NIL ){
      if( pair[u] != NIL )// decuplam daca avea o pereche inainte
        pair[pair[u]] = NIL;

      pair[u] = v;
      pair[v] = u;

      return true;
    }
  }

  for( int v : adj[u] )
    if( viz[v] != stamp ){
      viz[v] = stamp;
      if( match( pair[v] ) ){// incercam sa gasim alta pereche pentru perecea lui v
        if( pair[u] != NIL )// decuplam daca avea o pereche inainte
          pair[pair[u]] = NIL;

        pair[u] = v;
        pair[v] = u;

        return true;
      }
    }

  return false;
}


FILE *fin, *fout;

static inline int fgetint(){
  int n = 0, ch;

  while( !isdigit( ch = fgetc( fin ) ) );
  do
    n = n * 10 + ch - '0';
  while( isdigit( ch = fgetc( fin ) ) );

  return n;
}

int main(){
  fin  = fopen( "cuplaj.in",  "r" );
  fout = fopen( "cuplaj.out", "w" );

  int nl, nr, n, m, i, a, b, cuplaj;

  nl = fgetint();
  nr = fgetint();
  n = nl + nr;

  for( i = 0 ; i < n ; i++ )
    pair[i] = NIL;

  for( m = fgetint() ; m-- ; ){
    a = fgetint() - 1;
    b = fgetint() - 1 + nl;

    adj[a].push_back( b );
    adj[b].push_back( a );
  }

  for( i = 0 ; i < n ; i++ ) {
    match( i );
    stamp++;
  }


  cuplaj = 0;
  for( i = 0 ; i < nl ; i++ )
    cuplaj += (pair[i] != NIL);

  fprintf( fout, "%d\n", cuplaj );
  for( i = 0 ; i < nl ; i++ )
    if( pair[i] != NIL )
      fprintf( fout, "%d %d\n", i + 1, pair[i] - nl + 1 );

  fclose( fin );
  fclose( fout );
  return 0;
}