Cod sursa(job #2894436)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 27 aprilie 2022 20:29:22
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
// This program was written on 26-27.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];
unsigned short pair[MAXN];
unsigned char viz[MAXN];
int stamp;

bool match( int u ){
  viz[u] = stamp;
 
  // putem lega usor?
  for( int v : adj[u] ){
    if( pair[v] == 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
        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;
}

#include <sys/time.h>

inline long long getTime() {
  struct timeval tv;

  gettimeofday( &tv, NULL );
  return tv.tv_sec * 1000000LL + tv.tv_usec;
}

 
int main(){
  fin  = fopen( "cuplaj.in",  "r" );
  fout = fopen( "cuplaj.out", "w" );
 
  int nl, nr, n, m, i, j, a, b, cuplaj;
  long long dfs, reset;
 
  nl = fgetint();
  nr = fgetint();
  n = nl + nr;
  
  printf( "n = %d\n", n );
  
  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 );
  }

  dfs = reset = 0;
  stamp = 1;
  for( i = 0 ; i < nl ; i++ ) { // tb sa apelam doar la o jumatate din noduri
    dfs -= getTime();
    if( pair[i] == NIL )
        match( i );
    dfs += getTime();

    stamp++;

    reset -= getTime();
    if( stamp == 256 ){// in loc sa setam la 0 de fiecare data, folosim stamp si resetam doar de N/255 ori
      for( j = 0 ; j < n ; j++ )
        viz[j] = 0;

      stamp = 1;
    }
    reset += getTime();
  }
  
  printf( "dfs: %.2lfs\n", dfs / (1e6) );
  printf( "reset: %.2lfs\n", reset / (1e6) );
  
  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;
}