Pagini recente » Monitorul de evaluare | Cod sursa (job #2150014) | Cod sursa (job #1763376) | Cod sursa (job #2969080) | Cod sursa (job #608736)
Cod sursa(job #608736)
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define NMAX 355
#define INF 0x3f3f3f3f
#define pb push_back
#define MIN(a,b) (a<b) ? a : b
using namespace std;
ifstream in("fmcm.in");
ofstream out("fmcm.out");
int N, M, Sursa, Dest, Nod, Cnt, i, x, y, capacitate, cost, CostMin, FluxCt, Total;
int F[NMAX][NMAX], C[NMAX][NMAX], Cost[NMAX][NMAX], D[NMAX], T[NMAX], H[NMAX], Pos[NMAX];
vector< int > G[NMAX];
vector< int >::iterator Vecin;
queue< int > Q;
bool USED[NMAX];
inline void Swap( int a, int b )
{
int aux = H[a];
H[a] = H[b];
H[b] = aux;
Pos[ H[a] ] = a;
Pos[ H[b] ] = b;
}
inline void HeapDown( int NOD )
{
int Fiu = 2*NOD;
if( Fiu <= Cnt )
{
if( Fiu + 1 <= Cnt && D[ H[Fiu+1] ] < D[ H[Fiu] ] ) ++Fiu;
if( D[ H[Fiu] ] < D[ H[NOD] ] )
{
Swap( Fiu, NOD );
HeapDown( Fiu );
}
}
}
inline void HeapUp( int NOD )
{
if( NOD > 1 )
{
int T = NOD/2;
if( D[ H[T] ] > D[ H[NOD] ] )
{
Swap( T, NOD );
HeapUp( T );
}
}
}
inline void Bellman()
{
memset( D, INF, sizeof(D) );
D[Sursa] = 0;
memset( USED, false, sizeof(USED) );
Q.push( Sursa );
USED[Sursa] = true;
while( !Q.empty() )
{
int Nod = Q.front();
Q.pop();
USED[Nod] = false;
for( Vecin = G[Nod].begin(); Vecin != G[Nod].end(); Vecin++ )
if( F[Nod][*Vecin] < C[Nod][*Vecin] && D[*Vecin] > D[Nod] + Cost[Nod][*Vecin] )
{
D[*Vecin] = D[Nod] + Cost[Nod][*Vecin];
if( !USED[*Vecin] )
{
Q.push( *Vecin );
USED[*Vecin] = true;
}
}
}
Total = D[Dest];
}
inline bool Dijkstra()
{
for( Nod = 1; Nod <= N; Nod++ )
if( D[Nod] != INF )
for( Vecin = G[Nod].begin(); Vecin != G[Nod].end(); Vecin++ )
if( D[*Vecin] != INF )
Cost[Nod][*Vecin] += D[Nod] - D[*Vecin];
memset( D, INF, sizeof(D) );
D[Sursa] = 0;
memset( T, 0, sizeof(T) );
for( i = 1; i <= N; i++ )
H[i] = Pos[i] = i;
Swap( 1, Sursa );
Cnt = N;
while( Cnt && D[ H[1] ] != INF )
{
int Nod = H[1];
Swap( 1, Cnt-- );
HeapDown( 1 );
for( Vecin = G[Nod].begin(); Vecin != G[Nod].end(); Vecin++ )
if( F[Nod][*Vecin] < C[Nod][*Vecin] && D[*Vecin] > D[Nod] + Cost[Nod][*Vecin] )
{
D[*Vecin] = D[Nod] + Cost[Nod][*Vecin];
T[*Vecin] = Nod;
HeapUp( Pos[*Vecin] );
}
}
return ( D[Dest] != INF );
}
int main()
{
in >> N >> M >> Sursa >> Dest;
for( ; M--; )
{
in >> x >> y >> capacitate >> cost;
G[x].pb( y );
G[y].pb( x );
C[x][y] = capacitate;
Cost[x][y] = cost;
Cost[y][x] = -cost;
}
Bellman();
for( CostMin = 0; Dijkstra(); CostMin += FluxCt * Total )
{
FluxCt = INF;
for( Nod = Dest; Nod != Sursa; Nod = T[Nod] )
FluxCt = MIN( FluxCt, C[ T[Nod] ][Nod] - F[ T[Nod] ][Nod] );
for( Nod = Dest; Nod != Sursa; Nod = T[Nod] )
F[ T[Nod] ][Nod] += FluxCt, F[Nod][ T[Nod] ] -= FluxCt;
Total += D[Dest];
}
out << CostMin << '\n';
return 0;
}