Pagini recente » Rating Griffin (Griffin) | Cod sursa (job #72508) | Cod sursa (job #2829558) | Rating Duca Andrei (Andrei_x94) | Cod sursa (job #984724)
Cod sursa(job #984724)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <cassert>
using namespace std;
#define Nmax 355
#define INF 0x3f3f3f3f
class cmp
{
public:
bool operator()( const pair<int,int> &a, const pair<int,int> &b )
{
return a.second > b.second;
}
};
int N, M, S, D;
int flow, flow_cost;
vector <int> graph[Nmax];
int C[Nmax][Nmax];
int Cst[Nmax][Nmax];
int dist[Nmax];
int real_dist[Nmax];
int old_dist[Nmax];
int tata[Nmax];
bool in_queue[Nmax];
queue <int> Q;
priority_queue < pair<int,int>, vector <pair<int,int>>, cmp > heap;
inline bool Dijkstra( int source, int destination )
{
memset( dist, INF, sizeof( dist ) );
dist[source] = 0;
real_dist[source] = 0;
heap.push( make_pair( source, 0 ) );
while( !heap.empty() )
{
int cst = heap.top().second;
int nod = heap.top().first;
heap.pop();
if ( dist[nod] != cst )
continue;
for ( unsigned i = 0; i < graph[nod].size(); ++i )
{
int son = graph[nod][i];
if ( C[nod][son] )
{
int new_d = dist[nod] + Cst[nod][son] + old_dist[nod] - old_dist[son];
if ( new_d < dist[son] )
{
dist[son] = new_d;
real_dist[son] = real_dist[nod] + Cst[nod][son];
tata[son] = nod;
heap.push( make_pair( son, dist[son] ) );
}
}
}
}
memcpy( old_dist, real_dist, sizeof( old_dist ) );
if ( dist[destination] == INF )
return false;
int minim = INF, current_cost = 0, nod;
for ( nod = destination; nod != source; nod = tata[nod] )
minim = min( minim, C[ tata[nod] ][nod] ),
current_cost += C[ tata[nod] ][nod];
flow += minim;
flow_cost += minim * real_dist[destination];
for ( nod = destination; nod != source; nod = tata[nod] )
{
C[nod][ tata[nod] ] += minim;
C[ tata[nod] ][nod] -= minim;
}
return true;
}
inline bool BellmanFord( int source, int destination )
{
memset( old_dist, INF, sizeof( old_dist ) );
old_dist[source] = 0;
Q.push( source );
in_queue[source] = 1;
while( !Q.empty() )
{
int nod = Q.front();
Q.pop();
for ( unsigned i = 0; i < graph[nod].size(); ++i )
{
int son = graph[nod][i];
if ( C[nod][son] )
{
if ( old_dist[son] + Cst[nod][son] >= old_dist[son] )
continue;
old_dist[son] = old_dist[nod] + Cst[nod][son];
if ( in_queue[son] )
continue;
in_queue[son] = 1;
Q.push( son );
}
}
}
if ( old_dist[destination] == INF )
return false;
else
return true;
}
void read()
{
ifstream f("fmcm.in");
f >> N >> M >> S >> D;
for ( int x, y; M; M-- )
{
f >> x >> y;
f >> C[x][y] >> Cst[x][y];
graph[x].push_back( y );
graph[y].push_back( x );
Cst[y][x] = -Cst[x][y];
}
}
void print()
{
ofstream g("fmcm.out");
g << flow_cost << "\n";
g.close();
}
int main()
{
read();
BellmanFord( S, D );
for ( ; Dijkstra( S, D ); );
print();
return 0;
}