Pagini recente » Cod sursa (job #2033849) | Cod sursa (job #2665864) | Cod sursa (job #926833) | Cod sursa (job #1622740) | Cod sursa (job #2410364)
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>
#include <queue>
#include <algorithm>
#include <unordered_set>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int mx = -1, my = -1;
struct Edge
{
int v, u;
long long cap, flow = 0;
Edge(int v, int u, long long cap)
{
this->v = v;
this->u = u;
this->cap = cap;
}
};
struct Dinic
{
vector<vector<int>> adjList;
vector<Edge> edges;
vector<int> level, ptr;
queue<int> q;
long long flow_inf = numeric_limits<long long>::max();
int s, t, n, m = 0;
Dinic(int n, int s, int t, int expect)
{
this->s = s;
this->t = t;
this->n = n;
adjList.resize(n);
level.resize(n);
ptr.resize(n);
edges.reserve(expect);
}
void addEdge(int v, int u, long long cap = 1)
{
edges.emplace_back(v, u, cap);
edges.emplace_back(u, v, 0);
adjList[v].push_back(m);
adjList[u].push_back(m + 1);
m += 2;
}
bool bfs()
{
while (q.empty() == false)
{
int v = q.front();
q.pop();
int siz = static_cast<int>(adjList[v].size());
for (int i = 0; i < siz; i++)
{
int id = adjList[v][i];
if (level[edges[id].u] != -1 || edges[id].cap - edges[id].flow < 1)
continue;
level[edges[id].u] = level[v] + 1;
q.push(edges[id].u);
}
}
return level[t] != -1;
}
long long dfs(int v, long long pushed)
{
if (pushed == 0)
return 0;
if (v == t)
return pushed;
int siz = static_cast<int>(adjList[v].size());
for (int &cid = ptr[v]; cid < siz; cid++)
{
int id = adjList[v][cid];
int u = edges[id].u;
if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
continue;
long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
if (tr == 0)
continue;
edges[id].flow += tr;
edges[id ^ 1].flow -= tr;
return tr;
}
return 0;
}
void solve()
{
long long f = 0;
while (true)
{
fill(level.begin(), level.end(), -1);
q.push(s);
level[s] = 0;
if (!bfs())
break;
fill(ptr.begin(), ptr.end(), 0);
while (long long fl = dfs(s, flow_inf))
f += fl;
}
vector<pair<int, int>> sol;
for (auto a : edges)
{
if (a.flow == 1 && a.v != s && a.u != t)
sol.emplace_back(a.v, a.u);
}
fout << sol.size() << "\n";
for (auto a : sol)
{
fout << a.first - 1 << " " << a.second - mx - 1 << "\n";
}
}
};
int main()
{
int n, m, e;
fin >> n >> m >> e;
vector<pair<int, int>> LR(e);
unordered_set<int> Xm, Ym;
for (int i = 0; i < e; i++)
{
int x, y;
fin >> x >> y;
if (Xm.find(x) == Xm.end())
Xm.insert(x);
if (Ym.find(y) == Ym.end())
Ym.insert(y);
LR[i] = {x + 1, y + 1};
mx = max(mx, x);
my = max(my, y);
}
int sink = mx + my + 2;
Dinic D(n + m + 3, 1, sink, e);
for (auto a : LR)
{
D.addEdge(a.first, a.second+mx);
}
for (auto a : Xm)
{
D.addEdge(1, a + 1);
}
for (auto a : Ym)
{
D.addEdge(a + 1 + mx, sink);
}
D.solve();
return 0;
}