Pagini recente » Cod sursa (job #1595772) | Cod sursa (job #77197) | Cod sursa (job #3257888) | Cod sursa (job #1167184) | Cod sursa (job #1395809)
#include <fstream>
#include <vector>
#include <queue>
#define MAXV 10001
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
int L, R, E;
vector <int> G[2 * MAXV];
int match[2 * MAXV];
int father[2 * MAXV];
int maxMatch = 0;
int firstPath, secondPath;
bool addEdge;
inline void readAndBuild() {
in >> L >> R >> E;
int x, y;
for (int e = 0; e < E; ++ e) {
in >> x >> y;
G[x].push_back(y + L);
G[y + L].push_back(x);
}
}
inline bool bfs() {
queue <int> q;
for (int node = L + R; node > 0; -- node) {
if (match[node] == 0) {
father[node] = node;
q.push(node);
} else {
father[node] = -1;
}
}
// when q is empty, q.front() throws exception
// this loop avoids the case above
for (int node; !q.empty(); q.pop()) {
node = q.front();
bool edgeFromM;
if (match[node] != father[node] && node != father[node]) {
edgeFromM = true;
} else {
edgeFromM = false;
}
for (vector <int>::iterator it = G[node].begin(); it != G[node].end(); ++ it) {
if ((match[*it] == node) == edgeFromM) {
if (father[*it] == -1) {
father[*it] = node;
q.push(*it);
} else {
firstPath = node;
secondPath = *it;
addEdge = !edgeFromM;
return true;
}
}
}
}
return false;
}
inline void bipartiteMatchingWithEdmondsBlossom() {
for (int existsAugmentingPath = bfs(); existsAugmentingPath; existsAugmentingPath = bfs()) {
if (addEdge) {
match[firstPath] = secondPath;
match[secondPath] = firstPath;
}
for (int node = firstPath, sw = !addEdge; node != father[node]; node = father[node], sw = 1 - sw) {
if (sw == 1) {
match[node] = father[node];
match[father[node]] = node;
}
}
for (int node = secondPath, sw = !addEdge; node != father[node]; node = father[node], sw = 1 - sw) {
if (sw == 1) {
match[node] = father[node];
match[father[node]] = node;
}
}
maxMatch ++;
}
}
inline void printResult() {
out << maxMatch << '\n';
for (int i = 1; i <= L; ++ i)
if (match[i]) {
out << i << ' ' << match[i] - L << '\n';
}
}
int main() {
readAndBuild();
bipartiteMatchingWithEdmondsBlossom();
printResult();
return 0;
}