Pagini recente » Cod sursa (job #987113) | Cod sursa (job #2267141) | Cod sursa (job #1235935) | Cod sursa (job #1788889) | Cod sursa (job #1252874)
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
bool findMatch(
const int u,
vector<int>& matchInU,
vector<int>& matchInV,
vector<bool>& tested,
const vector<vector<int>>& E) {
if (tested[u]) return false;
tested[u] = true;
for (int v : E[u])
if (matchInU[v] == -1 ||
findMatch(matchInU[v], matchInU, matchInV, tested, E)) {
// if v is unmatched or if we can free v
matchInU[v] = u;
matchInV[u] = v;
return true;
}
return false;
}
int main() {
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int nU, nV, edges; fin >> nU >> nV >> edges;
// Representation of a bipartite graph G = (U + V, E), stores only the edges
// linking nodes in U to nodes in V i.e. for any u in U, if v in E[u] then
// there is an edge (u, v) in E.
// U = {0, 1, ..., nU-1}, V = {0, 1, ..., nV-1}
vector<vector<int>> E(nU);
for (int u, v; edges--;) {
fin >> u >> v; u--, v--;
E[u].push_back(v);
}
// keep track of the vertices in U which we have already tried to match
vector<bool> tested(nU, false);
vector<int> matchInU(nV, -1), // map from V to U
matchInV(nU, -1); // map from U to V
// greedy algorithm to find the maximum matching
int max_matching = 0;
for (bool changed = true; changed; ) {
changed = false;
fill(tested.begin(), tested.end(), false);
for (int u = 0; u < nU; ++u)
if (matchInV[u] == -1 && findMatch(u, matchInU, matchInV, tested, E)) {
changed = true;
max_matching++;
}
}
// output a maximum matching
fout << max_matching << '\n';
for (int u = 0; u < nU; ++u) if (matchInV[u] != -1)
fout << u+1 << ' ' << matchInV[u]+1 << '\n';
return 0;
}