Pagini recente » Cod sursa (job #2068025) | Cod sursa (job #1624754) | Cod sursa (job #98993) | Cod sursa (job #931496) | Cod sursa (job #2247771)
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <vector>
#include <stack>
#include <set>
#include <assert.h>
#include <queue>
#include <chrono>
#include <memory>
using LL = long long;
using ULL = int long long;
const std::string _problemName = "cuplaj";
namespace std {
std::ifstream fin(_problemName + ".in");
std::ofstream fout(_problemName + ".out");
}
#define USE_FILES
#ifdef USE_FILES
#define cin fin
#define cout fout
#endif
using graph_t = std::vector< std::vector<int> >;
int n, m, e;
graph_t edgesFromLeft;
std::vector<int> matchesFromLeft;
std::vector<int> matchesFromRight;
std::vector<int> leftVisited;
void doMatch(int leftNode, int rightNode) {
matchesFromLeft [leftNode] = rightNode;
matchesFromRight[rightNode] = leftNode ;
}
bool doImproveSimple(int leftNode) {
for (int rightNode : edgesFromLeft[leftNode]) {
if (matchesFromRight[rightNode] == -1) {
doMatch(leftNode, rightNode);
return true;
}
}
return false;
}
bool doImprove(int leftNode);
bool doImproveWithReassign(int leftNode) {
for (int rightNode : edgesFromLeft[leftNode]) {
// assert matchesFromRight[rightNode] != -1
if (doImprove(matchesFromRight[rightNode])) {
doMatch(leftNode, rightNode);
return true;
}
}
return false;
}
bool doImprove(int leftNode) {
if (leftVisited[leftNode]) {
return false;
}
leftVisited[leftNode] = true;
bool improved = false;
improved = improved || doImproveSimple(leftNode);
improved = improved || doImproveWithReassign(leftNode);
return improved;
}
bool doImprove() {
bool improved = false;
std::fill(leftVisited.begin(), leftVisited.end(), false);
for (int leftNode = 0; leftNode < n; ++leftNode) {
if (matchesFromLeft[leftNode] == -1) {
improved = improved | doImprove(leftNode);
}
}
return improved;
}
int main() {
std::cin >> n >> m >> e;
edgesFromLeft.resize(n);
matchesFromLeft.resize(n);
matchesFromRight.resize(m);
std::fill(matchesFromLeft.begin(), matchesFromLeft.end(), -1);
std::fill(matchesFromRight.begin(), matchesFromRight.end(), -1);
leftVisited.resize(n);
while (e--) {
int x, y;
std::cin >> x >> y;
--x, --y;
edgesFromLeft[x].push_back(y);
}
bool improved;
do {
improved = doImprove();
} while (improved);
std::vector< std::pair<int, int> > matching;
for (int leftIdx = 0; leftIdx < matchesFromLeft.size(); ++leftIdx) {
int rightNode = matchesFromLeft[leftIdx];
if (rightNode != -1) {
matching.emplace_back(leftIdx, rightNode);
}
}
std::cout << matching.size() << '\n';
for (auto pair : matching) {
std::cout << pair.first + 1 << ' ' << pair.second + 1 << '\n';
}
return 0;
}