Pagini recente » Cod sursa (job #833966) | Cod sursa (job #1217193) | Cod sursa (job #1933319) | Cod sursa (job #2234345) | Cod sursa (job #2960674)
#pragma GCC optimize "O3"
#include <algorithm>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int n, x, y, g[1001][1001];
queue <int> q;
bool visited[1001];
int parinte[1001];
// Intoarce un boolean care arata daca a gasit sau nu macar un drum de ameliorare.
bool bfs() {
while (q.empty() == false)
q.pop();
for (int i = 0; i <= n; i++) {
parinte[i] = 0;
visited[i] = false;
}
int sursa = 1;
q.push(sursa);
visited[sursa] = true;
while (!q.empty()) {
int nod = q.front();
q.pop();
if (nod == n)
// Am ajuns la destinatie, deci am gasit un drum.
return true;
for (int i = 1; i <= n; i++)
if (!visited[i] && g[nod][i] > 0) {
q.push(i);
parinte[i] = nod;
visited[i] = true;
}
}
return false;
}
int flux() {
int maxFlow = 0;
// Atata timp cat mai exista drumuri de ameliorare, inseamna ca mai putem adauga flux.
while (bfs()) {
for (int i = 1; i < n; i++) {
if (g[i][n] > 0 && visited[i]) {
int frunza = i;
vector <int> drum;
drum.push_back(n);
drum.push_back(frunza);
int nod = parinte[frunza];
if (nod == 1)
drum.push_back(nod);
else {
while (nod != 1) {
drum.push_back(nod);
nod = parinte[nod];
}
drum.push_back(1);
}
// Fac reverse la vector, pentru ca ordinea elementelor sa fie de la nodul de start spre destinatie.
reverse(drum.begin(), drum.end());
int minCap = 2e9;
for (int i = 0; i < drum.size() - 1; i++)
minCap = min(minCap, g[drum[i]][drum[i + 1]]);
maxFlow += minCap;
for (int i = 0; i < drum.size() - 1; i++) {
// Scad capacitatea minima din muchiile drumului.
g[drum[i]][drum[i+1]] -= minCap;
// Adaug la muchiile inverse.
g[drum[i+1]][drum[i]] += minCap;
}
}
}
}
return maxFlow;
}
int main() {
int cap, m;
fin >> n >> m;
for (int i = 0; i < m; i++) {
fin >> x >> y >> cap;
g[x][y] = cap;
}
fout << flux();
return 0;
}