Pagini recente » Cod sursa (job #2244230) | Cod sursa (job #2134631) | Cod sursa (job #1327366) | Cod sursa (job #147261) | Cod sursa (job #442131)
Cod sursa(job #442131)
# include <fstream>
# include <iostream>
# include <vector>
# include <queue>
using namespace std;
const int MAXN = 512, inf = 2000000001;
int maxFlow, minCost;
int N, M, S, D, pqSize;
int cap [ MAXN ] [ MAXN ], cost [ MAXN ] [ MAXN ];
int dist [ MAXN ], from [ MAXN ], pq [ MAXN ], poz [ MAXN ];
bool viz [ MAXN ], popped [ MAXN ];
vector <int> G [ MAXN ];
queue <int> q;
void interch ( int &a, int &b ){
int aux;
aux = a;
a = b;
b = aux;
}
void BellmanFord (){
int i;
vector <int> :: iterator it;
for ( i = 1; i <= N; ++ i )
dist [ i ] = inf;
dist [ S ] = 0;
q . push ( S );
while ( ! q. empty () ){
for ( it = G [ q . front () ] . begin (); it != G [ q . front () ] . end (); ++ it )
if ( cap [ q . front () ] [ * it ] > 0 && dist [ q . front () ] != inf
&& dist [ * it ] > dist [ q . front () ] + cost [ q . front () ] [ * it ] ){
dist [ * it ] = dist [ q . front () ] + cost [ q . front () ] [ * it ];
q . push ( * it );
}
q . pop ();
}
}
void graphTransform (){
int i;
vector <int> :: iterator it;
for ( i = 1; i <= N; ++ i )
for ( it = G [ i ] . begin (); it != G [ i ] . end (); ++ it )
cost [ i ] [ * it ] += dist [ i ] - dist [ * it ];
}
void pqInsert ( int x ){
int p;
pq [ p = ++ pqSize ] = x;
while ( p != 1 && dist [ pq [ p ] ] < dist [ pq [ p / 2 ] ] ){
interch ( pq [ p ], pq [ p / 2 ] );
poz [ pq [ p ] ] = p;
p = p / 2;
}
poz [ x ] = p;
}
bool pqEmpty (){
return ( pqSize == 0 );
}
int pqMin (){
return pq [ 1 ];
}
void pqUpdate ( int x ){
// key [ x ] only decreases
int p = poz [ x ];
while ( p != 1 && dist [ pq [ p ] ] < dist [ pq [ p / 2 ] ] ){
interch ( pq [ p ], pq [ p / 2 ] );
poz [ pq [ p ] ] = p;
}
poz [ x ] = p;
}
void heapify ( int po ){
int minv, p;
p = po;
minv = dist [ pq [ po ] ];
if ( 2 * po <= pqSize && dist [ 2 * po ] < minv ){
p = po * 2;
minv = dist [ 2 * po ];
}
if ( 2 * po + 1 <= pqSize && dist [ 2 * po + 1 ] < minv ){
p = po * 2;
minv = dist [ 2 * po + 1 ];
}
if ( p != po ){
interch ( pq [ p ], pq [ po ] );
poz [ pq [ p ] ] = p;
poz [ pq [ po ] ] = po;
heapify ( p );
}
}
void pqPop(){
interch ( pq [ 1 ], pq [ pqSize ] );
poz [ pq [ 1 ] ] = 1;
poz [ pq [ pqSize ] ] = pqSize;
-- pqSize;
heapify ( 1 );
}
void oneSourceMultipleDestinationsMinPaths (){
// Dijkstra
int i, x;
vector <int> :: iterator it;
memset ( viz, 0, sizeof ( viz ) );
memset ( from, -1, sizeof ( from ) );
memset ( popped, 0, sizeof ( popped ) );
for ( i = 1; i <= N; ++ i )
dist [ i ] = inf;
dist [ S ] = 0;
pqInsert ( S );
while ( ! pqEmpty () ){
x = pqMin ();
popped [ x ] = true;
for ( it = G [ x ] . begin (); it != G [ x ] . end (); ++ it )
if ( cap [ x ] [ * it ] > 0 && dist [ * it ] > dist [ x ] + cost [ x ] [ * it ] ){
dist [ * it ] = dist [ x ] + cost [ x ] [ * it ];
from [ * it ] = x;
if ( ! viz [ * it ] )
pqInsert ( * it );
else if ( ! popped [ * it ] )
pqUpdate ( * it );
viz [ * it ] = true;
}
pqPop ();
}
}
void findAugmentingPathOfMinCost ( int &flow, int &cst ){
int dad;
flow = inf; cst = 0;
oneSourceMultipleDestinationsMinPaths ();
if ( from [ D ] == -1 ){
flow = 0;
return;
}
dad = D;
while ( from [ dad ] != -1 ){
cst += cost [ from [ dad ] ] [ dad ];
if ( cap [ from [ dad ] ] [ dad ] < flow )
flow = cap [ from [ dad ] ] [ dad ];
dad = from [ dad ];
}
dad = D;
while ( from [ dad ] != -1 ){
cap [ dad ] [ from [ dad ] ] += flow;
cap [ from [ dad ] ] [ dad ] -= flow;
dad = from [ dad ];
}
}
void fmcm (){
int flux, cst;
BellmanFord ();
do{
// make graph costs nonnegative
graphTransform ();
findAugmentingPathOfMinCost ( flux, cst );
maxFlow += flux;
minCost += flux * cst;
} while ( flux > 0 );
}
void creareGraf (){
/* Graful contine cel mult un arc intre oricare doua noduri x si y,
iar daca ( x, y ) apartine lui E, atunci ( y, x ) nu apartine lui E,
unde E este multimea arcelor */
int i, x, y;
ifstream f ( "fmcm.in" );
f >> N >> M >> S >> D;
for ( i = 0; i < M; ++ i ){
f >> x >> y;
f >> cap [ x ] [ y ] >> cost [ x ] [ y ];
cost [ y ] [ x ] = - cost [ x ] [ y ];
G [ x ] . push_back ( y );
G [ y ] . push_back ( x );
}
f . close ();
}
void afis (){
ofstream g ( "fmcm.out" );
g << minCost << '\n';
g . close ();
}
int main(){
creareGraf ();
fmcm ();
afis ();
return 0;
}