Pagini recente » Cod sursa (job #3326429) | Cod sursa (job #3328617) | Cod sursa (job #3322774) | Cod sursa (job #3328620) | Cod sursa (job #3328608)
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
const int N_MAX = 20005;
const int INF = 1e9;
struct edge {
int to, rev;
int cap, flow;
};
std::vector<edge> G[N_MAX];
int parent[N_MAX];
int parentIndex[N_MAX];
int n, m, e;
int bfs(int s, int d) {
for(int i = 0; i < N_MAX; i++) {
parent[i] = -1;
}
std::queue<int> q;
q.push(s);
parent[s] = -2;
while(!q.empty()) {
int nod = q.front();
q.pop();
if(nod == d) break;
for (size_t i = 0; i < G[nod].size(); i++) {
edge &e = G[nod][i];
if(parent[e.to] == -1 && e.cap > e.flow) {
parent[e.to] = nod;
parentIndex[e.to] = i;
q.push(e.to);
}
}
}
if(parent[d] == -1) {
return 0;
}
int flow = INF;
int curr = d;
while(curr != s) {
int prev = parent[curr];
int edgeIndex = parentIndex[curr];
flow = std::min(flow, G[prev][edgeIndex].cap - G[prev][edgeIndex].flow);
curr = prev;
}
curr = d;
while(curr != s) {
int prev = parent[curr];
int edgeIndex = parentIndex[curr];
G[prev][edgeIndex].flow += flow;
int revIndex = G[prev][edgeIndex].rev;
G[curr][revIndex].flow -= flow;
curr = prev;
}
return flow;
}
void add_edge(int from, int to, int cap) {
edge forward = {to, (int)G[to].size(), cap, 0};
edge backward = {from, (int)G[from].size(), 0, 0};
G[from].push_back(forward);
G[to].push_back(backward);
}
int main() {
std::ifstream fin("cuplaj.in");
std::ofstream fout("cuplaj.out");
fin >> n >> m >> e;
int source = 0;
int sink = n + m + 1;
for(int i = 1; i <= n; i++) {
add_edge(source, i, 1);
}
for(int i = 1; i <= m; i++) {
add_edge(n + i, sink, 1);
}
for(int i = 0; i < e; i++) {
int u, v;
fin >> u >> v;
add_edge(u, n + v, 1);
}
int maxflow = 0;
while (true) {
int flow = bfs(source, sink);
if(flow == 0) {
break;
}
maxflow += flow;
}
fout << maxflow << '\n';
for(int u = 1; u <= n; u++) {
for (auto &e : G[u]) {
if(e.to != source && e.flow > 0) {
fout << u << ' ' << e.to - n << '\n';
}
}
}
}