Cod sursa(job #3132914)

Utilizator vladburacBurac Vlad vladburac Data 24 mai 2023 12:46:58
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
/// Hopcroft-Karp Algorithm for finding Maximum Matching Algorithm
/// Complexity: O( sqrt(( N + M )) * E ), where N and M are the number of nodes on each side
/// and E, the number of edges

/// difference between this and the standard version is that we find as many alternating
/// paths as possible, using a bfs for grouping the vertices on layers
/// and a dfs for finding the shortest alternating path for every vertex

#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e4;
const int NIL = 0;
const int INF = 1e9;
ifstream fin( "cuplaj.in" );
ofstream fout( "cuplaj.out" );

class BipartiteGraph{
  int n, m;
  vector <int> edges[NMAX+1];
  int dist[NMAX+1];
  public:
    int pairU[NMAX+1], pairV[NMAX+1];
    BipartiteGraph( int n, int m );
    void addEdge( int u, int v );
    bool bfs();
    bool dfs( int node );
    int hopcroftKarp();
};

BipartiteGraph::BipartiteGraph( int n, int m ) {
  this->n = n;
  this->m = m;
}

void BipartiteGraph::addEdge( int u, int v ) {
  edges[u].push_back( v );
}

bool BipartiteGraph::bfs() {
  queue <int> q;
  int u, i;
  for( i = 1; i <= n; i++ ) {
    if( pairU[i] == NIL ) {
      q.push( i );
      dist[i] = 0;
    }
    else
      dist[i] = INF;
  }
  dist[NIL] = INF;
  while( !q.empty() ) {
    u = q.front();
    q.pop();
    for( auto vec: edges[u] ) {
      if( dist[pairV[vec]] == INF ) {
        q.push( pairV[vec] );
        dist[pairV[vec]] = dist[u] + 1;
      }
    }
  }
  return ( dist[NIL] != INF );
}

bool BipartiteGraph::dfs( int node ) {
  if( node != NIL ) {
    for( auto vec: edges[node] ) {
      if( dist[pairV[vec]] == dist[node] + 1 ) {
        if( dfs( pairV[vec] ) ) {
          pairV[vec] = node;
          pairU[node] = vec;
          return true;
        }
      }
    }
    dist[node] = INF;
    return false;
  }
  return true;
}

int BipartiteGraph::hopcroftKarp() {
  int i, ans;
  for( i = 1; i <= n; i++ )
    pairU[i] = NIL;
  for( i = 1; i <= m; i++ )
    pairV[i] = NIL;
  ans = 0;
  while( bfs() ) {
    for( i = 1; i <= n; i++ ) {
      if( pairU[i] == NIL && dfs( i ) )
        ans++;
    }
  }
  return ans;
}

int main() {
  int n, m, i, a, b, e;
  fin >> n >> m >> e;
  BipartiteGraph cuplaj( n, m );
  for( i = 0; i < e; i++ ) {
    fin >> a >> b;
    cuplaj.addEdge( a, b );
  }
  fout << cuplaj.hopcroftKarp() << "\n";
  for( i = 1; i <= n; i++ ) {
    if( cuplaj.pairU[i] != NIL )
      fout << i << " " << cuplaj.pairU[i] << "\n";
  }
  return 0;
}