Pagini recente » Cod sursa (job #2413071) | Cod sursa (job #1052553) | Cod sursa (job #3286039) | Cod sursa (job #1973314) | Cod sursa (job #2956322)
/*
Procedam analog problemei Flux maxim, cu diferenta ca toate capacitatile vor fi 1
si vom adauga grafului doua noduri inainte de a rula flux pe el:
-> un nod de start care are muchie cu toate nodurile din primul set
-> un nod de final care are muchie cu toate nodurile din al doilea set
Rulam algoritmul de determinare a fluxului maxim si rezultatul va fi cuplajul cautat.
Pentru a obtine muchiile ce alcatuiesc cuplajul, vom afisa muchiile care leaga un nod
din primul set cu un nod din al doilea set si au capacitate 0 (adica le-am utilizat).
Pentru reprezentarea grafului, am indexat nodurile astfel:
-> nod start = 0
-> primul set: 1 .. n
-> al doilea set: n + 1 .. n + m
-> nod final = n + m + 1
*/
#include <bits/stdc++.h>
int flow_after_BFS (std::vector<std::vector<int>> &adj_list,
std::vector<std::vector<int>> &capacity,
std::vector<int> &previous) {
int n = adj_list.size() - 1;
std::vector<bool> sel(n + 1, false);
std::queue<int> bf_queue;
bf_queue.push(0);
sel[0] = true;
while (!bf_queue.empty()) {
int current = bf_queue.front();
bf_queue.pop();
for (auto nbh : adj_list[current]) {
if (!sel[nbh] && capacity[current][nbh] > 0 && nbh != n) {
sel[nbh] = true;
bf_queue.push(nbh);
previous[nbh] = current;
}
}
}
int max_flow_possible = 0;
for (auto nbh : adj_list[n]) {
if (!sel[nbh]) continue;
int current_path_flow = capacity[nbh][n];
int current = nbh;
while (current != 0) {
current_path_flow = std::min(current_path_flow, capacity[previous[current]][current]);
current = previous[current];
}
capacity[nbh][n] -= current_path_flow;
capacity[n][nbh] += current_path_flow;
current = nbh;
while (current != 0) {
capacity[previous[current]][current] -= current_path_flow;
capacity[current][previous[current]] += current_path_flow;
current = previous[current];
}
max_flow_possible += current_path_flow;
}
return max_flow_possible;
}
int get_max_flow (std::vector<std::vector<int>> &adj_list,
std::vector<std::vector<int>> &capacity) {
int n = adj_list.size() - 1;
std::vector<int> previous(n + 1, -1);
int total_max_flow = 0;
int path_flow = flow_after_BFS(adj_list, capacity, previous);
while (path_flow) {
total_max_flow += path_flow;
path_flow = flow_after_BFS(adj_list, capacity, previous);
}
return total_max_flow;
}
int main()
{
std::ifstream fin("cuplaj.in");
std::ofstream fout("cuplaj.out");
int n, m, e;
fin >> n >> m >> e;
std::vector<std::vector<int>> adj_list(n + m + 2);
std::vector<std::vector<int>> capacity(n + m + 2, std::vector<int>(m + n + 2, 0));
for (int i = 1; i <= e; ++i) {
int node1, node2;
fin >> node1 >> node2;
adj_list[node1].push_back(node2 + n);
adj_list[node2 + n].push_back(node1);
capacity[node1][node2 + n] = 1;
}
for (int i = 1; i <= n; ++i) {
adj_list[0].push_back(i);
adj_list[i].push_back(0);
capacity[0][i] = 1;
}
for (int i = n + 1; i <= n + m; ++i) {
adj_list[i].push_back(m + n + 1);
adj_list[m + n + 1].push_back(i);
capacity[i][m + n + 1] = 1;
}
fout << get_max_flow(adj_list, capacity) << '\n';
for (int i = 1; i <= n; ++i)
for (auto j : adj_list[i])
if (!capacity[i][j] && j) fout << i << " " << j - n << '\n';
return 0;
}