Pagini recente » Cod sursa (job #1292947) | Cod sursa (job #384485) | Cod sursa (job #1168818) | Cod sursa (job #1353791) | Cod sursa (job #1395979)
#include <fstream>
#include <vector>
#include <cstring>
#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 root;
int firstUnmatched;
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 dfs(int node, int parity) {
for (vector <int>::iterator it = G[node].begin(); it != G[node].end(); ++ it) {
if ((match[*it] != node) == parity) {
if (father[*it] == -1) {
father[*it] = node;
if (match[*it] == 0 && *it != root) {
match[node] = *it;
match[*it] = node;
return true;
}
bool foundPath = dfs(*it, 1 - parity);
if (foundPath) {
if (parity == 1) {
match[node] = *it;
match[*it] = node;
}
return true;
}
}
}
}
return false;
}
inline bool dfsLoop() {
memset(father, -1, sizeof(father));
for (int node = firstUnmatched; node > 0; -- node) {
if (match[node] == 0) {
root = node;
father[node] = node;
bool foundPath = dfs(node, 1);
if (foundPath) {
firstUnmatched = node;
while (firstUnmatched <= L && match[firstUnmatched] != 0) {
firstUnmatched ++;
}
return true;
}
}
}
return false;
}
inline void bipartiteMatchingWithEdmondsBlossom() {
firstUnmatched = L;
for (bool existsAugmentingPath = dfsLoop(); existsAugmentingPath; existsAugmentingPath = dfsLoop()) {
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;
}