Cod sursa(job #3259823)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 27 noiembrie 2024 22:09:50
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <random>
#include <time.h>

const int MAXN = 2e5;
const int NIL = -1;

const int MAX_BAD = 10;

std::vector<int> adj[MAXN];
int pair[MAXN];
bool viz[MAXN];

bool try_pair( int u ) {
  viz[u] = true;

  for( int v : adj[u] )
    if( pair[v] == NIL ){
      pair[v] = u;
      pair[u] = v;
      return true;
    }
    
  for( int v : adj[u] )
    if( !viz[v] ){
      viz[v] = true;

      if( try_pair( pair[v] ) ){
        pair[v] = u;
        pair[u] = v;
        return true;
      }
    }
    
  return false;
}

int main() {
  FILE *fin = fopen( "cuplaj.in", "r" );
  FILE *fout = fopen( "cuplaj.out", "w" );
  
  std::mt19937 rng(clock());
  int l, r, m;
  fscanf( fin, "%d%d%d", &l, &r, &m );

  for( int i = 0; i < m; i++ ){
    int a, b;
    fscanf( fin, "%d%d", &a, &b );
    a--;
    b--;
    
    b += l;

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

  for( int i = 0; i < l + r; i++ )
    pair[i] = NIL;

  int bad_rounds = 0;
  while( bad_rounds < MAX_BAD ){
    for( int i = 0; i < l + r; i++ ){
      viz[i] = false;
      std::shuffle( adj[i].begin(), adj[i].end(), rng );
    }

    bool good = false;
    for( int i = 0; i < l; i++ )
      if( !viz[i] && pair[i] == NIL )
        good |= try_pair( i );

    bad_rounds += !good;
  }

  std::vector<std::pair<int, int>> ans;
  for( int i = 0; i < l; i++ )
    if( pair[i] != NIL )
      ans.emplace_back( i, pair[i] - l );

  fprintf( fout, "%d\n", (int)ans.size() );
  for( auto edge : ans )
    fprintf( fout, "%d %d\n", edge.first + 1, edge.second + 1 );

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