Pagini recente » Cod sursa (job #2007385) | Cod sursa (job #856875) | Cod sursa (job #1641196) | Cod sursa (job #1443886) | Cod sursa (job #3132914)
/// 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;
}