Pagini recente » Monitorul de evaluare | Cod sursa (job #749337) | Cod sursa (job #3339211) | Cod sursa (job #775286) | Cod sursa (job #3334682)
#include <fstream>
#include<vector>
#include <queue>
#define inf 1e9
using namespace std;
ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");
int N, M, E;
int source = 0;
int sink;
vector<vector<int>> graph;
vector<vector<int>> cuplaj;
vector<bool> viz;
vector<int> tata;
int total_value;
int cuplaj_maxim;
bool bfs() {
tata.assign(total_value, 0);
viz.assign(total_value, 0);
viz[source] = 1;
queue<pair<int,int>> q;
q.push({source, inf});
while (!q.empty()) {
int top = q.front().first;
int flow = q.front().second;
q.pop();
for (auto e : graph[top]) {
if ( !viz[e] && cuplaj[top][e] > 0) {
tata[e] = top;
viz[e] = 1;
int pushed = min(flow, cuplaj[top][e]);
if (e == sink)
return true;
q.push({e, pushed});
}
}
}
return false;
}
int Edmunds_karp() {
while (bfs()) {
int bottleneck = inf;
int current = sink;
while (current != source) {
int prev = tata[current];
bottleneck = min(bottleneck, cuplaj[prev][current]);
current = prev;
}
current = sink;
while (current != source) {
int prev = tata[current];
cuplaj[prev][current] -= bottleneck;
cuplaj[current][prev] += bottleneck;
current = prev;
}
cuplaj_maxim +=bottleneck;
}
return cuplaj_maxim;
}
/*
*FORD FULKERSON
int dfs(int node, int flux_curent) {
if (node == sink) return flux_curent;
viz[node] = true;
for (auto e : graph[node]) {
if (!viz[e] && cuplaj[node][e] > 0) {
int bottleneck = min(flux_curent, cuplaj[node][e]);
int flux_pushed = dfs(e, bottleneck);
if (flux_pushed > 0) {
cuplaj[node][e] -= flux_pushed;
cuplaj[e][node] += flux_pushed;
return flux_pushed;
}
}
}
return 0;
}
*/
int main() {
cin >> N >> M >> E;
total_value = N + M + 2;
graph.resize(total_value);
cuplaj.resize(total_value);
viz.resize(total_value);
sink = N + M + 1;
for (int i = 0; i <= N + M + 1; i++)
cuplaj[i].resize(total_value);
for (int i = 0; i < E; i++) {
int u, v;
cin >> u >> v;
//legam muchiile
graph[u].push_back(N + v);
graph[N + v].push_back(u);
// legam sursa de nodurile din L
graph[source].push_back(u);
graph[u].push_back(source);
//legam nodurile din R de sink
graph[N+v].push_back(sink);
graph[sink].push_back(N+v);
//adaugam capacitatile
cuplaj[u][N + v] = 1;
cuplaj[source][u] = 1;
cuplaj[N + v][sink] = 1;
}
// ford fulkerson
/*
while (true) {
viz.assign(N+M+2, false);
int pushed = dfs(source, 1e9);
if (!pushed)
break;
cuplaj_maxim += pushed;
}
*/
cout << Edmunds_karp() << endl;
// reconstruirea drumului
for (int i = 1; i <= N; i++)
for (auto e : graph[i]) {
if (e > N && e < sink && cuplaj[i][e] == 0)
cout << i << " " << e - N << "\n";
}
return 0;
}