Pagini recente » Cod sursa (job #433722) | Cod sursa (job #191518) | Cod sursa (job #2197637) | Cod sursa (job #1915730) | Cod sursa (job #1867413)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <tuple>
#include <limits>
#include <functional>
#include <complex>
#include <bitset>
#include <list>
//#include <atomic>
//#include <condition_variable>
//#include <future>
//#include <mutex>
//#include <thread>
using namespace std;
#define debug(x) cerr << #x << " = " << x << "\n"
const int INF = 0x3f3f3f3f;
const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
struct Dinic
{
static const int InfCapacity = 0x3f3f3f3f;
struct Edge
{
int to;
int capacity;
int rev;
};
vector<vector<Edge> > g;
void init(int n)
{
g.assign(n, vector<Edge>());
}
void add(int i, int j, int capacity)
{
Edge e, f;
e.to = j, f.to = i;
e.capacity = capacity, f.capacity = 0;
g[i].push_back(e);
g[j].push_back(f);
g[i].back().rev = (int) g[j].size() - 1;
g[j].back().rev = (int) g[i].size() - 1;
}
void addB(int i, int j, int capacity)
{
Edge e, f;
e.to = j, f.to = i;
e.capacity = capacity, f.capacity = capacity;
g[i].push_back(e);
g[j].push_back(f);
g[i].back().rev = (int) g[j].size() - 1;
g[j].back().rev = (int) g[i].size() - 1;
}
int maximum_flow(int s, int t)
{
int n = (int) g.size();
vector<int> level(n);
int total = 0;
bool update;
do
{
update = false;
fill(level.begin(), level.end(), -1);
level[s] = 0;
queue<int> q;
q.push(s);
for (int d = n; !q.empty() && level[q.front()] < d;)
{
int u = q.front();
q.pop();
if (u == t) d = level[u];
for (Edge &e : g[u])
{
if (e.capacity > 0 && level[e.to] == -1)
{
q.push(e.to);
level[e.to] = level[u] + 1;
}
}
}
vector<int> iter(n);
for (int i = 0; i < n; i++) iter[i] = (int) g[i].size() - 1;
while (true)
{
int f = augment(level, iter, s, t, InfCapacity);
if (f == 0) break;
total += f;
update = true;
}
} while (update);
return total;
}
int augment(vector<int>& level, vector<int>& iter, int u, int t, int f)
{
if (u == t || f == 0) return f;
int lv = level[u];
if (lv == -1) return 0;
level[u] = -1;
for (; iter[u] >= 0; --iter[u])
{
Edge &e = g[u][iter[u]];
if (level[e.to] <= lv) continue;
int l = augment(level, iter, e.to, t, min(f, e.capacity));
if (l == 0) continue;
e.capacity -= l;
g[e.to][e.rev].capacity += l;
level[u] = lv;
return l;
}
return 0;
}
};
const int Dinic::InfCapacity;
int main(int argc, char* argv[])
{
freopen("cuplaj.in", "r", stdin);
freopen("cuplaj.out", "w", stdout);
cin.sync_with_stdio(false);
int l, r, n;
cin >> l >> r >> n;
int s = 0, t = l + r + 1;
Dinic mf; mf.init(l + r + 2);
for (int i = 1; i <= l; i++) mf.add(s, i, 1);
for (int i = l + 1; i <= l + r; i++) mf.add(i, t, 1);
for (int i = 0; i < n; i++)
{
int x, y;
cin >> x >> y;
mf.add(x, l + y, 1);
}
const vector< vector<Dinic::Edge> >& g = mf.g;
cout << mf.maximum_flow(s, t) << "\n";
for (int i = 1; i <= l; i++)
{
for (const Dinic::Edge& e : g[i])
{
if (e.capacity == 0 && e.to - l > 0)
{
cout << i << " " << e.to - l << "\n";
break;
}
}
}
return 0;
}