Pagini recente » Cod sursa (job #704499) | Cod sursa (job #2238433) | Cod sursa (job #1928974) | Cod sursa (job #1145203) | Cod sursa (job #698838)
Cod sursa(job #698838)
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define Nmax 355
#define INF 2147000000
#define pb push_back
using namespace std;
vector< int > v[Nmax];
queue< int > Q;
int F[Nmax][Nmax],C[Nmax][Nmax],Cost[Nmax][Nmax];
int dist[Nmax],h[Nmax],poz[Nmax],prev[Nmax],inq[Nmax];
int N,M,S,D,Sum,ok,cost_flow,dh;
inline void read()
{
int i,x,y,cap,cost;
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
scanf("%d%d%d%d",&N,&M,&S,&D);
for(i=1; i<=M; ++i)
{
scanf("%d%d%d%d",&x,&y,&cap,&cost);
v[x].pb(y);
v[y].pb(x);
C[x][y] = cap;
Cost[x][y] = cost;
Cost[y][x] = -cost;
}
}
inline void BF()
{
vector< int >:: iterator it;
int f;
memset( prev, 0, sizeof(prev) );
while( ! Q.empty() ) Q.pop();
Q.push( S );
inq[ S ] = 1;
for(int i = 1; i<=N; ++i) dist[i] = INF;
dist[S] = 0;
while( ! Q.empty() )
{
f = Q.front(); Q.pop();
inq[ f ] = 0;
if( f == D ) continue;
for( it=v[f].begin(); it!=v[f].end(); ++it)
if( C[f][*it] > F[f][*it] && dist[*it] > dist[f] + Cost[f][*it] )
{
dist[*it] = dist[f] + Cost[f][*it];
if( ! inq[ *it] )
{
inq[ *it ] = 1;
Q.push( *it );
}
}
}
Sum = dist[ D ];
}
inline void swap( int i, int j)
{
int aux;
aux=h[i], h[i] = h[j], h[j]=aux;
poz[h[i]] = i;
poz[h[j]] = j;
}
inline void Up( int k )
{
while ( k/2 && dist[ h[k] ] < dist[ h[k/2] ] )
{
swap( k, k/2 );
k/=2;
}
}
inline void Down( int k )
{
int mn=0;
while( mn != k )
{
mn = k;
if( mn*2 <= dh && dist[ h[mn*2] ] < dist[ h[k] ] ) k = 2*mn;
if( mn*2+1 <= dh && dist[ h[mn*2+1] ] < dist[ h[k] ] ) k = 2*mn+1;
swap( k, mn );
}
}
inline void Flux()
{
vector< int >:: iterator it;
int i,pmin,fmin,wh;
for( i=1; i<=N; ++i)
if( dist[ i ] != INF )
for( it=v[i].begin(); it!=v[i].end(); ++it)
if( dist[*it] != INF )
Cost[ i ][ *it ] += dist[i] - dist[*it];
for( i=1; i<=N; ++i ) dist[i] = INF, h[i]=poz[i]=i, prev[i] = 0;
dist[ S ] = 0;
dh = N;
Up( S );
while( dh && dist[ h[1] ] != INF )
{
pmin = h[1];
swap( 1, dh );
dh--;
Down( 1 );
for( it=v[pmin].begin(); it!=v[pmin].end(); ++it )
if( C[pmin][*it] > F[pmin][*it] && dist[ *it ] > dist[ pmin ] + Cost[pmin][*it] )
{
dist[ *it ] = dist[ pmin ] + Cost[pmin][*it];
prev[ *it ] = pmin;
Up( poz[ *it ] );
}
}
if( dist[ D ] == INF ) return;
ok = 1;
fmin = INF;
for( wh = D; wh != S; wh = prev[ wh ] )
fmin = min( fmin, C[prev[wh]][wh] - F[prev[wh]][wh] );
for( wh = D; wh != S; wh = prev[ wh ] )
{
F[prev[wh]][wh] += fmin;
F[wh][prev[wh]] -= fmin;
}
Sum += dist[ D ];
cost_flow += Sum * fmin;
}
int main()
{
read();
BF();
do
{
ok = 0;
Flux();
} while( ok );
printf("%d\n",cost_flow);
fclose(stdin); fclose(stdout);
return 0;
}