Pagini recente » Cod sursa (job #811807) | Cod sursa (job #805058) | Cod sursa (job #1117909) | Cod sursa (job #2318619) | Cod sursa (job #3241681)
#include <bits/stdc++.h>
using namespace std;
struct AugmentedPath {
bool hasPath;
vector<pair<int, int>> path;
AugmentedPath(bool _hasPath, const vector<pair<int, int>>& _path)
: hasPath(_hasPath)
, path(_path) { }
operator bool() const {
return hasPath;
}
};
class EdmondsKarp { // T = O(m * n)
public:
void solve() {
read_input();
print_output(get_result());
}
private:
int n, m, e;
vector<vector<int>> adj;
vector<vector<int>> cap;
vector<pair<int, int>> cuplaj;
void read_input() {
ifstream fin("cuplaj.in");
fin >> n >> m >> e;
cap.resize(n + m + 2, vector<int>(n + m + 2, 0));
adj.resize(n + m + 2);
for (int i = 0, u, v; i < e; i++) {
fin >> u >> v;
v += n;
adj[u].push_back(v);
adj[v].push_back(u);
cap[u][v] = 1;
}
for (int i = 1; i <= n; ++i) {
adj[0].push_back(i); // Sursa este nodul 0
adj[i].push_back(0);
cap[0][i] = 1;
}
for (int i = n + 1; i <= n + m; ++i) {
adj[i].push_back(n + m + 1); // Destinația este nodul n + m + 1
adj[n + m + 1].push_back(i);
cap[i][n + m + 1] = 1;
}
fin.close();
}
int get_result() {
return get_maxflow(n + m + 2, 0, n + m + 1);
}
int get_maxflow(int nodes, int source, int sink) {
int total_flow = 0;
vector<vector<int>> flow(nodes, vector<int>(nodes, 0));
while (auto res = bfs(nodes, source, sink, flow)) {
auto& [_, path] = res;
int minFluxPath = INT32_MAX;
for (auto& [u, v] : path) {
minFluxPath = min(minFluxPath, cap[u][v] - flow[u][v]);
}
total_flow += minFluxPath;
for (auto& [u, v] : path) {
flow[u][v] += minFluxPath;
flow[v][u] -= minFluxPath;
}
}
for (int i = 1; i <= n; ++i) {
for (int j = n + 1; j <= m + n; ++j) {
if (flow[i][j] == 1) {
cuplaj.push_back({i, j - n});
}
}
}
return total_flow;
}
AugmentedPath bfs(int nodes, int source, int sink, vector<vector<int>>& flow) {
vector<int> p(nodes, -1);
queue<int> q;
q.push(source);
p[source] = 0;
while (!q.empty()) {
int node = q.front();
q.pop();
for (auto& neigh : adj[node]) {
if (p[neigh] == -1 && flow[node][neigh] < cap[node][neigh]) {
p[neigh] = node;
q.push(neigh);
}
}
}
if (p[sink] == -1) {
return {false, {}};
}
vector<pair<int, int>> path;
int node = sink;
do {
path.push_back({p[node], node});
node = p[node];
} while (node);
reverse(path.begin(), path.end());
return {true, path};
}
void print_output(int result) {
ofstream fout("cuplaj.out");
fout.tie(0);
fout << result << "\n";
for (const auto& edge : cuplaj) {
fout << edge.first << " " << edge.second << "\n";
}
fout.close();
}
};
int main() {
ios::sync_with_stdio(false);
auto* task = new (nothrow) EdmondsKarp();
//auto* task = new (nothrow) HopcroftKarp();
if (!task) {
cerr << "new failed\n";
return -1;
}
task->solve();
delete task;
return 0;
}