FMATCH - Fast Maximum Matching
Tác giả: RR
Ngôn ngữ: C++
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <complex>
#include <iostream>
#include <algorithm>
#include <ctime>
#include <deque>
#include <bitset>
#include <cctype>
#include <utility>
#include <cassert>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--)
#define REP(i,a) for(int i=0,_a=(a); i<_a; i++)
#define EACH(it,a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#define DEBUG(x) { cout << #x << " = "; cout << (x) << endl; }
#define PR(a,n) { cout << #a << " = "; FOR(_,1,n) cout << a[_] << ' '; cout << endl; }
#define PR0(a,n) { cout << #a << " = "; REP(_,n) cout << a[_] << ' '; cout << endl; }
#define sqr(x) ((x) * (x))
using namespace std;
// Index from 1
const int inf = 1000111;
struct Matching {
int n;
vector<int> matchL, matchR, dist;
vector<bool> seen;
vector< vector<int> > ke;
Matching(int n) : n(n), matchL(n+1), matchR(n+1), dist(n+1), seen(n+1, false), ke(n+1) {}
void addEdge(int u, int v) {
ke[u].push_back(v);
}
bool bfs() {
queue<int> qu;
FOR(u,1,n) if (!matchL[u]) {
dist[u] = 0;
qu.push(u);
} else dist[u] = inf;
dist[0] = inf;
while (!qu.empty()) {
int u = qu.front(); qu.pop();
for(__typeof(ke[u].begin()) v = ke[u].begin(); v != ke[u].end(); ++v) {
if (dist[matchR[*v]] == inf) {
dist[matchR[*v]] = dist[u] + 1;
qu.push(matchR[*v]);
}
}
}
return dist[0] != inf;
}
bool dfs(int u) {
if (u) {
for(__typeof(ke[u].begin()) v = ke[u].begin(); v != ke[u].end(); ++v)
if (dist[matchR[*v]] == dist[u] + 1 && dfs(matchR[*v])) {
matchL[u] = *v;
matchR[*v] = u;
return true;
}
dist[u] = inf;
return false;
}
return true;
}
int match() {
int res = 0;
while (bfs()) {
FOR(u,1,n)
if (!matchL[u])
if (dfs(u)) ++res;
}
return res;
}
};
int main() {
ios :: sync_with_stdio(false); cin.tie(NULL);
int m, n, p;
while (cin >> m >> n >> p) {
Matching match(max(m, n));
while (p--) {
int u, v; cin >> u >> v;
match.addEdge(u, v);
}
cout << match.match() << endl;
}
}