Pagini recente » Cod sursa (job #255304) | Cod sursa (job #428257) | Cod sursa (job #464297) | Cod sursa (job #2642759) | Cod sursa (job #2962193)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
// Declare input and output files
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int leftSize, rightSize, edges, source, sink;
vector<bool> existingRight;
vector<pair<int, int>> parent;
vector<pair<int, int>> rightNodes;
vector<vector<pair<int, pair<int, int>>>> adjacency;
queue<int> q;
void addEdge(int u, int v) {
adjacency[u].push_back({v, {1, adjacency[v].size()}});
adjacency[v].push_back({u, {0, adjacency[u].size() - 1}});
if (v == sink)
rightNodes.emplace_back(u, adjacency[u].size() - 1);
}
bool bfs() {
vector<bool> visited(sink + 1);
q.push(source);
visited[source] = true;
parent[source] = {-1, -1};
while (!q.empty()) {
int currentNode = q.front();
q.pop();
if (currentNode == sink) continue;
int c = 0;
for (auto node: adjacency[currentNode]) {
int a, b;
a = node.first;
b = node.second.first;
if (!visited[a] && b) {
parent[a] = {currentNode, c};
visited[a] = true;
q.push(a);
}
c++;
}
}
return visited[sink];
}
long int maxFlow() {
long int max_flow = 0;
while (bfs()) {
for (auto node: rightNodes) {
int u, v, x, y, min_path = 1;
parent[sink] = node;
v = sink;
// Trace the path back to the source
while (parent[v].first != -1) {
u = parent[v].first;
x = parent[v].second;
// Update the minimum path capacity
min_path = min(min_path, adjacency[u][x].second.first);
v = u;
}
// Update the capacities of the edges and the reverse edges along the path
v = sink;
while (parent[v].first != -1) {
u = parent[v].first;
x = parent[v].second;
y = adjacency[u][x].second.second;
adjacency[u][x].second.first -= min_path;
adjacency[v][y].second.first += min_path;
v = u;
}
// Increase the maximum flow by the minimum path capacity
max_flow += min_path;
}
}
return max_flow;
}
int main() {
fin >> leftSize >> rightSize >> edges;
source = 0;
sink = leftSize + rightSize + 1;
existingRight.resize(rightSize + 1);
parent.resize(sink + 1);
adjacency.resize(sink + 1);
for (int i = 1; i <= leftSize; i++)
addEdge(source, i);
for (int i = 1; i <= edges; i++) {
int u, v;
fin >> u >> v;
addEdge(u, leftSize + v);
existingRight[v] = true;
}
// Add edges from each node on the right side that has an incoming edge to the sink
for (int i = 1; i <= rightSize; i++) {
if (existingRight[i])
addEdge(leftSize + i, sink);
}
fout << maxFlow() << '\n';
for (int u = 1; u <= leftSize; u++)
for (auto node: adjacency[u]) {
int v, c;
v = node.first;
c = node.second.first;
if (v && c == 0 && v != sink)
fout << u << " " << v - leftSize << '\n';
}
return 0;
}