Pagini recente » Cod sursa (job #3217682) | Cod sursa (job #263061) | Cod sursa (job #2716931) | Cod sursa (job #5373) | Cod sursa (job #3298706)
#include <bits/stdc++.h>
#define int long long
#define ld long double
using namespace std;
/*
* Usage:
Dinic<5010> dinic;
int N; int M; cin >> N >> M;
dinic.setup(1, N);
for (int i = 0; i < M; i++) {
int u, v, cap; cin >> u >> v >> cap;
dinic.add_edge(u, v, cap);
}
cout << dinic.max_flow();
*/
template<int N>
struct Dinic {
private:
struct Edge {
int from; int to;
int flow; int capacity;
Edge(int a, int b, int c, int d) : from(a), to(b), flow(c), capacity(d) {}
int remainingCapacity() const { return capacity - flow; }
};
int level[N], source, sink, next[N];
vector<int> adj[N];
vector<Edge> edges;
public:
void setup(int source, int sink) { this->source = source; this->sink = sink; }
void add_edge(int u, int v, int cap) {
adj[u].emplace_back(edges.size());
edges.emplace_back(u, v, 0, cap);
adj[v].emplace_back(edges.size());
edges.emplace_back(v, u, 0, 0);
}
bool do_levels() {
memset(level, 0, sizeof(level));
level[source] = 1;
deque<int> dq; dq.emplace_back(source);
while (!dq.empty()) {
int curNode = dq.front(); dq.pop_front();
for (auto edgeIndex : adj[curNode]) {
const auto& edge = edges[edgeIndex];
if (level[edge.to] == 0 && edge.remainingCapacity() > 0) {
level[edge.to] = level[edge.from] + 1;
dq.emplace_back(edge.to);
}
}
}
return level[sink] != 0;
}
int push_flow(int curNode, int flow) {
if (curNode == sink) return flow;
for (int& edgeOrder = next[curNode]; edgeOrder < adj[curNode].size(); edgeOrder++) {
int edgeIndex = adj[curNode][edgeOrder];
const auto& edge = edges[edgeIndex];
if (level[edge.from] + 1 == level[edge.to] && edge.remainingCapacity() > 0) {
int f = push_flow(edge.to, min(flow, edge.remainingCapacity()));
if (f > 0) {
edges[edgeIndex].flow += f;
edges[edgeIndex ^ 1].flow -= f;
return f;
}
}
}
return 0;
}
int max_flow() {
int ans = 0;
while (do_levels()) {
memset(next, 0, sizeof(next));
while (long long flow = push_flow(source, LONG_MAX)) {
ans += flow;
}
}
return ans;
}
};
// Inspired by: https://infoarena.ro/job_detail/3297319?action=view-source
int L, R, M;
int p[10'010];
bool viz[10'010];
vector<int> adj[10'010];
bool pair_up(int node) {
if (viz[node]) return false;
viz[node] = true;
for (auto neigh : adj[node]) {
if (!p[neigh] || pair_up(p[neigh])) {
p[node] = neigh;
p[neigh] = node;
return true;
}
}
return false;
}
int32_t main() {
cin.tie(0)->sync_with_stdio(0);
#ifdef N257
freopen("input.txt", "r", stdin);
#else
freopen("cuplaj.in", "r", stdin);
freopen("cuplaj.out", "w", stdout);
#endif
// Setup the graph
cin >> L >> R >> M;
for (int i = 0; i < M; i++) {
int leftNode, rightNode; cin >> leftNode >> rightNode;
rightNode += L;
adj[leftNode].emplace_back(rightNode);
// adj[rightNode].emplace_back(leftNode);
}
bool dai = true;
int cnt = 0;
while ( dai ) {
dai = false;
memset(viz, 0, sizeof(viz));
for (int i = 1; i <= L; i++) {
if (!p[i] && pair_up(i)) {
dai = true;
cnt++;
}
}
}
cout << cnt << '\n';
for (int i = 1; i <= L; i++) {
if (p[i])
cout << i << ' ' << p[i] << '\n';
}
}