Pagini recente » Cod sursa (job #2915361) | Cod sursa (job #1555553) | Cod sursa (job #364694) | Cod sursa (job #1832781) | Cod sursa (job #2961827)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
int l, r, m;
class Flow
{
int source, sink;
int n;
// std::vector<bool> visited;
std::vector<std::vector<int> > graph;
// std::vector<std::vector<int> > capacity;
std::unordered_map<int, std::unordered_map<int, int>> flow;
std::vector<int> father;
// void dfs(int x) {
// visited[x] = true;
// for (int node : graph[x]) {
// if (!visited[node] && flow[x][node] > 0) {
// dfs(node);
// }
// }
// }
bool bfs()
{
father.assign(n+1, 0);
std::queue<int> q;
q.push(source);
while(!q.empty())
{
int node = q.front();
q.pop();
for(int neighbour : graph[node])
{
if(!father[neighbour] && flow[node][neighbour] > 0) {
q.push(neighbour);
father[neighbour] = node;
if (neighbour == sink)
return true;
}
}
}
return false;
}
public:
Flow(int n, int source, int sink)
{
this->source = source;
this->sink = sink;
this->n = n;
// capacity.resize(n + 1, std::vector<int>(n + 1));
flow.reserve(n + 1);
graph.resize(n + 1);
father.resize(n + 1);
}
void addEdge(int x, int y, int c = 1)
{
graph[x].push_back(y);
graph[y].push_back(x);
//flow is an unordered_map of pairs of ints and ints
flow[x][y] = c;
}
int getMaxFlow()
{
int maxFlow = 0;
do{
if( !bfs() )
break;
for (auto nod : graph[n]) {
if(!flow[nod][n] || !father[nod])
continue;
father[n] = nod;
int flowMin = 0x7fffffff;
for (int i = n; i; i = father[i]) {
flowMin = std::min(flowMin, flow[father[i]][i]);
}
if (flowMin == 0)
continue;
maxFlow += flowMin;
for (int i = n; i; i = father[i]) {
flow[father[i]][i] -= flowMin;
flow[i][father[i]] += flowMin;
}
}
} while (true);
return maxFlow;
}
// std::vector<std::pair<int, int>> getMinCut()
// {
// visited.reset();
// dfs(source);
// std::vector<std::pair<int, int>> minCut;
// for (int i = 1; i <= n; ++i) {
// for (int j : graph[i]) {
// if (visited[i] && !visited[j] && flow[i][j] > 0)
// minCut.emplace_back(i, j);
// }
// }
// return minCut;
// }
void printGraph() {
for (int j = l + 1; j <= n; ++j) {
for (int i = 1; i <= l; ++i) {
if (flow[j][i] > 0)
out << i << ' ' << j - l << '\n';
}
}
}
};
int main()
{
in >> l >> r >> m;
Flow f(l + r + 1, 0, l + r + 1);
for (int i = 1; i <= l; ++i)
f.addEdge(0, i);
for (int i = l + 1; i <= l + r; ++i)
f.addEdge(i, l + r + 1);
int x, y;
while (m--) {
in >> x >> y;
f.addEdge(x, l + y);
}
in.close();
int sol = f.getMaxFlow();
out << sol << '\n';
f.printGraph();
out.close();
}