Pagini recente » Cod sursa (job #2329248) | Cod sursa (job #430282) | Cod sursa (job #439167) | Cod sursa (job #437267) | Cod sursa (job #777016)
Cod sursa(job #777016)
// Vom explica fluxul ca fiind o retea de trinsport ( sa zicem ceva tevi )
// Fiecare teava are o capacitate data , nepund sa curga mai multa apa prin
// teava respectiva. Tu trebuie sa intuiesti mersul apei. Pesupund ca apa curge
// intr-un minut din punctul de start la cel tina , cata apa ajunge la final
// pe minut.
// Ca si graf , se poate intui ca graful este unidirectional. Exemplu:
//
// Start -> A ( maxim 3 ) -> C( maxim 3 ) |
// -> B ( maxim 1 ) |-> C( maxim 5 )| -> End ( maxim 2 )
// |-> D( maxim 4 ) -> E( maxim 2 ) -> End ( maxim 3 )
// REZULTAT : 3;
//
// Consideram tevile ca fiind bidirectionale , capacitatile pundau-se modifica
// pe parcursul algoritmului. Initial arcele de forma y -> x au capacitate 0
// Daca trece o catitate de apa prin teava x -> y , atunci Cap[x][y]-=c.
// Daca capacitate intr-o parte scade , atunci capacitate opusa crest Cap[y][x]+=c
// Bazandu-ne pe aceasta observatie la fiecare pas vom contrui arborele BFS si ne
// vom opri doar cand nu se mai poate ajunge la punctul tinta prin BFS.
// La fiecare pas trimite flux de la Start la nodurile legate de End.
// ( in exemplu C si E )
// Consecitele fiecarui pas sunt modifcarile arborelui BFS din cauza fluctuatiei
// capacitatii muchiilor.
// In final Complexitatea este O(N*M*M) amortizat
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
const int Nmax=1011;
const int Mmax=5011;
const int oo=0x3f3f3f3f;
int Cap[Nmax][Nmax];
int Dad[Nmax],Marked[Nmax];
vector<int> Leg[Nmax];
int N,M,Flux,Fmin;
ifstream F("maxflow.in");
ofstream G("maxflow.out");
int cd[Nmax];
int BF()
{
int i, j, nod, V;
cd[0] = 1;
cd[1] = 1;
memset(Marked, 0, sizeof(Marked));
Marked[1] = 1;
for (i = 1; i <= cd[0]; i++)
{
nod = cd[i];
if (nod == N) continue;
for (j = 0; j < int(Leg[nod].size()); j++)
{
V = Leg[nod][j];
if ( Cap[nod][V]==0 || Marked[V]) continue;
Marked[V] = 1;
cd[ ++cd[0] ] = V;
Dad[V] = nod;
}
}
return Marked[N];
}
int main()
{
F>>N>>M;
for (int i=1;i<=M;++i)
{
int x,y,z;
F>>x>>y>>z;
Cap[x][y]=z;
Leg[x].push_back( y );
Leg[y].push_back( x );
}
for ( Flux=0;BF(); )
for (int i=0; i < int(Leg[N].size()) ; ++i)
{
int Nod=Leg[N][i];
if ( Cap[Nod] == 0 || !Marked[Nod] ) continue;
Dad[N]=Nod;
Fmin=oo;
for (int Act=N; Act!=1; Act=Dad[Act] )
Fmin=min( Fmin, Cap[ Dad[Act] ][Act] );
if ( Fmin == 0 ) continue;
for (int Act = N; Act != 1; Act = Dad[Act])
{
Cap[ Dad[Act] ][Act] -= Fmin;
Cap[Act][ Dad[Act] ] += Fmin;
}
Flux+=Fmin;
}
G<<Flux<<'\n';
}