Pagini recente » Cod sursa (job #2537213) | Cod sursa (job #610491) | Cod sursa (job #530225) | Cod sursa (job #2737772) | Cod sursa (job #3266222)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int n, m, s, t, e, flux_initial = 0;
vector<vector<int>> la;
vector<vector<int>> capacitate, flux;
vector<int> tata;
void Read()
{
// fie s = 0 si t = n + m + 1
f >> n >> m >> e;
s = 0;
t = n + m + 1;
la.resize(n + m + 2);
capacitate.resize(n + m + 2, vector<int>(n + m + 2, 0));
// INIȚIALIZĂM FLUXUL NUL
flux.resize(n + m + 2, vector<int>(n + m + 2, 0));
tata.resize(n + m + 2, -1);
int x, y;
for (int i = 1; i <= e; i++)
{
f >> x >> y;
la[x].push_back(n + y);
la[n + y].push_back(x);
capacitate[x][n + y] = 1;
}
// initializam la[s] cu muchiile corespunzătoare
for (size_t i = 1; i <= n; i++)
{
la[s].push_back(i);
// flux[s][i] = 1;
capacitate[s][i] = 1;
}
for (size_t i = n + 1; i <= n + m; i++)
{
la[i].push_back(t);
capacitate[i][t] = 1;
}
}
bool ConstruiesteDrumBF()
{
int nod;
vector<bool> viz(n + m + 2, false);
viz[s] = true;
tata.assign(n + m + 2, -1);
queue<int> q;
q.push(s);
while (!q.empty())
{
int nod_curent = q.front();
q.pop();
for (auto &vecin : la[nod_curent])
{
// daca vecinul este vizitat sau capacitatea este folosită la maxim sărim peste
if (viz[vecin] || capacitate[nod_curent][vecin] <= flux[nod_curent][vecin])
continue;
q.push(vecin);
viz[vecin] = true;
tata[vecin] = nod_curent;
// dacă am ajuns la destinația finală
if (vecin == t)
return true;
}
}
return false;
}
int main()
{
Read();
int flow = flux_initial, fmin;
while (ConstruiesteDrumBF())
{
fmin = INT_MAX;
// aflam capacitatea reziduală minimă
for (int nod = t; nod != s; nod = tata[nod])
{
fmin = min(fmin, capacitate[tata[nod]][nod] - flux[tata[nod]][nod]);
}
// revizuim fluxul
for (int nod = t; nod != s; nod = tata[nod])
{
// actualizam pe muchiile directe
flux[tata[nod]][nod] += fmin;
// actualizam pe muchiile inverse
flux[nod][tata[nod]] -= fmin;
}
flow += fmin;
}
g << flow << '\n';
for (size_t nod = 1; nod <= n; nod++)
{
for (auto &vecin : la[nod])
{
if (flux[nod][vecin] == 1)
g << nod << ' ' << vecin - n << '\n';
}
}
return 0;
}