Pagini recente » Cod sursa (job #2085260) | Cod sursa (job #751377) | Cod sursa (job #2446866) | Cod sursa (job #1524653) | Cod sursa (job #3189882)
#include <vector>
#include <queue>
#include <climits>
#include <fstream>
#define NIL 0
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
struct Edge {
int to;
int flow;
int capacity;
int reverse;
};
class HopkroftKarp {
int N, M;
vector<int> rightCorrespondent, leftCorrespondent, level;
vector<vector<int>> adj;
public:
HopkroftKarp(int N, int M);
void addEdge(int u, int v);
bool bfs();
bool dfs(int leftNode);
int hopkroft();
void printMatches();
};
HopkroftKarp::HopkroftKarp(int n, int m) : N(n), M(m), leftCorrespondent(n + 1), rightCorrespondent(m + 1), level(n + 1), adj(n + 1) {}
void HopkroftKarp::addEdge(int u, int v) {
adj[u].push_back(v);
}
bool HopkroftKarp::bfs() {
queue<int> q;
level.assign(N + 1, INT_MAX);
// add unmatched first layer vertices
for (int i = 1; i <= N; ++i) {
if (rightCorrespondent[i] == NIL) {
level[i] = 0;
q.emplace(i);
}
}
while (!q.empty()) {
int leftNode = q.front();
q.pop();
// found unmatched left vertex
if (leftNode == NIL) {
break;
}
for (auto &rightNode: adj[leftNode]) {
if (level[leftCorrespondent[rightNode]] == INT_MAX) {
level[leftCorrespondent[rightNode]] = level[leftNode] + 1;
q.emplace(leftCorrespondent[rightNode]);
}
}
}
// this means that an unmatched left vertex was reached, which is what we want
return level[NIL] != INT_MAX;
}
bool HopkroftKarp::dfs(int leftNode) {
if (leftNode == NIL) {
return true;
}
for (auto &rightNode: adj[leftNode]) {
if (level[leftCorrespondent[rightNode]] == level[leftNode] + 1 && dfs(leftCorrespondent[rightNode])) {
rightCorrespondent[leftNode] = rightNode;
leftCorrespondent[rightNode] = leftNode;
return true;
}
}
// TODO
level[leftNode] == INT_MAX;
return false;
}
int HopkroftKarp::hopkroft() {
leftCorrespondent.assign(M + 1, NIL);
rightCorrespondent.assign(N + 1, NIL);
int answer = 0;
while (bfs()) {
for (int i = 1; i <= N; ++i) {
if (rightCorrespondent[i] == NIL && dfs(i)) {
answer++;
}
}
}
return answer;
}
void HopkroftKarp::printMatches() {
for (int i = 1; i <= N; ++i) {
if (rightCorrespondent[i] != NIL) {
fout << i << " " << rightCorrespondent[i] << endl;
}
}
}
int main()
{
int N, M, E, x, y;
fin >> N >> M >> E;
HopkroftKarp algorithm(N, M);
while (E--) {
fin >> x >> y;
algorithm.addEdge(x, y);
}
fout << algorithm.hopkroft() << endl;
algorithm.printMatches();
return 0;
}