Pagini recente » Cod sursa (job #2893001) | Profil FlorinHaja | Cod sursa (job #2500943) | Cod sursa (job #541243) | Cod sursa (job #2643744)
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 2020;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
struct Muchie
{
int de_la, pana_la, cap, flux, poz;
Muchie(int de_la, int pana_la, int cap, int flux, int poz) :
de_la(de_la), pana_la(pana_la), cap(cap), flux(flux), poz(poz) {}
};
struct Dinic
{
int N;
vector<vector<Muchie> > G;
vector<Muchie*> tata; /// Ca sa economisesc memoria, altfel ar trebui sa retin muchia ori ceva cu pozitia muchiei in lista de adiacenta
Dinic(int N) : N(N), G(N), tata(N) {}
/// Si incepe de la 0
void PuneMuchia(int de_la, int pana_la, int cap)
{
G[de_la].push_back(Muchie(de_la, pana_la, cap, 0, G[pana_la].size()));
if (de_la == pana_la) G[de_la].back().poz++;
G[pana_la].push_back(Muchie(pana_la, de_la, 0, 0, G[de_la].size() - 1));
cin.get();
}
/// s = sursa, t = tinta / target
long long GasesteFluxBlocant(int s, int t)
{
fill(tata.begin(), tata.end(), (Muchie*)NULL);
tata[s] = &G[0][0] - 1; /// aritmetica pe pointeri
unsigned int x, i;
queue< int > q;
q.push(s);
while (!q.empty())
{
x = q.front();
q.pop();
for (i = 0; i < G[x].size(); ++i)
{
Muchie& e = G[x][i];
if (!tata[e.pana_la] && e.cap - e.flux > 0)
{
tata[e.pana_la] = &G[x][i];
q.push(e.pana_la);
}
}
}
if (!tata[t]) return 0;
/// Trimit fluxul cu un DFS. Neoptimizat, nu ma folosesc de nivelurile pe care sunt nodurile
long long flux_total = 0;
for (i = 0; i < G[t].size(); ++i)
{
/// Folosesc muchiile inverse
Muchie* start = &G[G[t][i].pana_la][G[t][i].poz];
int marire_flux = INF;
Muchie* e = start;
while (marire_flux > 0 && e != tata[s])
{
if (!e)
{
marire_flux = 0;
break;
}
marire_flux = min(marire_flux, e->cap - e->flux);
e = tata[e->de_la];
}
if (marire_flux == 0)
continue;
e = start;
while (marire_flux > 0 && e != tata[s])
{
e->flux += marire_flux;
G[e->pana_la][e->poz].flux -= marire_flux;
e = tata[e->de_la];
}
flux_total += marire_flux;
}
return flux_total;
}
long long FluxMaxim(int s, int t)
{
long long flux_total = 0;
while (long long flux = GasesteFluxBlocant(s, t))
flux_total += flux;
return flux_total;
}
};
int main()
{
int t;
int n, m;
fin >> n >> m;
Dinic D(n);
int a, b, c;
int s = 0;
int tinta = n - 1;
for (int i = 1; i <= m; i++)
{
fin >> a >> b >> c;
D.PuneMuchia(a-1, b-1, c);
}
fout << D.FluxMaxim(s, tinta) << "\n";
return 0;
}