Pagini recente » Cod sursa (job #2882416) | Cod sursa (job #1466765) | Cod sursa (job #739584) | Cod sursa (job #2663572) | Cod sursa (job #3042204)
#include <bits/stdc++.h>
#define int long long
using namespace std;
//#define LOCAL
#ifdef LOCAL
ifstream in("in.in");
ofstream out("out.out");
#else
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
#endif
const int inf = (1LL << 61);
namespace MaxFlow {
struct Edge {
int to,rev,cap,flow;
};
vector<Edge> edges;
vector<vector<int>> g;
vector<int> parent,dis,parentEdge,last_edge;
void init(int n) {
g.resize(n + 1);
dis.resize(n + 1);
parent.resize(n +1);
parentEdge.resize(n+1);
last_edge.resize(n+1);
}
void add_edge(int u, int v, int cap) {
//cout << "add edge " << u << " " << v << "\n";
g[u].push_back(edges.size());
edges.push_back(Edge{v,(int)edges.size(),cap,0});
g[v].push_back(edges.size());
edges.push_back(Edge{u,(int)edges.size() - 1, 0, 0});
}
int dif(const Edge &v) {
return v.cap - v.flow;
}
bool bfs(int s, int t) {
fill(dis.begin(),dis.end(),inf);
fill(parent.begin(),parent.end(),-1);
queue<int> q;
dis[s] = 0;
q.push(s);
while(!q.empty()) {
int node = q.front();
q.pop();
for (auto e : g[node]) {
int to = edges[e].to;
if (dis[node] + 1 < dis[to] && dif(edges[e])) {
dis[to] = dis[node] + 1;
parent[to] = node;
parentEdge[to] = e;///the edge that got us here
q.push(to);
}
}
}
return (parent[t] != -1);
}
int push_flow(int node, int t, int flow) {
if (node == t) {
return flow; /// we can push as much flow as we care from here
}
for (int &i = last_edge[node]; i < g[node].size(); i++) {
int free = dif(edges[g[node][i]]);
if (free == 0) continue;
int k = edges[g[node][i]].to;
if (dis[k] != dis[node] + 1) {
continue;
}
int pushed_flow = push_flow(k,t,min(flow,free));
if (pushed_flow > 0) { // we can actually push flow yay
edges[g[node][i]].flow += pushed_flow;
edges[g[node][i]^1].flow -= pushed_flow;
return pushed_flow;
}
}
return 0;
}
int get_flow(int s, int t) {
int total_flow = 0;
while(bfs(s,t)) {
fill(last_edge.begin(), last_edge.end(),0);
while(int p = push_flow(s,t,inf)) {
total_flow += p;
}
}
return total_flow;
}
}
int n,m,e;
int32_t main() {
in >> n >> m >> e;
MaxFlow::init(n + m + 1);
for (int i = 1; i <= n; i++) {
MaxFlow::add_edge(0,i,1);
}
for (int i = 1; i <=m; i++) {
MaxFlow::add_edge(i + n, n + m + 1,1);
}
for (int i = 1; i <= e; i++) {
int u,v;
in >> u >> v;
MaxFlow::add_edge(u,v + n,1);
}
out << MaxFlow::get_flow(0,n+m+1) << "\n";
for (int i = 1; i <= n; i++) {
for (auto k : MaxFlow::g[i]) {
if (MaxFlow::edges[k].flow > 0) {
out << i << " " << -n + MaxFlow::edges[k].to << "\n";
}
}
}
}