Pagini recente » Cod sursa (job #1876723) | Cod sursa (job #139855) | Cod sursa (job #1866793) | Cod sursa (job #2491945) | Cod sursa (job #3266221)
#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;
}
// for (size_t nod = 1; nod <= la.size() - 1; nod++)
// {
// for (size_t vecin = 0; vecin < la[nod].size(); vecin++)
// {
// g << nod << ' ' << la[nod][vecin] << ' ' << flux[nod][la[nod][vecin]] << '\n';
// }
// }
g << flow << '\n';
// int nod;
// vector<bool> viz(n + 1, false);
// viz[s] = true;
// 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])
// continue;
// else if (capacitate[nod_curent][vecin] == flux[nod_curent][vecin])
// {
// g << nod_curent << ' ' << vecin << '\n';
// 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;
return 0;
}