Pagini recente » Cod sursa (job #446619) | Cod sursa (job #1387449) | Cod sursa (job #1668438) | Cod sursa (job #1934038) | Cod sursa (job #2072162)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
const int MAX_N = 350;
int cost[1 + MAX_N][1 + MAX_N];
int flow[1 + MAX_N][1 + MAX_N];
int rel_cost[1 + MAX_N][1 + MAX_N];
vector<int> edges[1 + MAX_N];
int dist[1 + MAX_N];
int rel_dist[1 + MAX_N];
int from[1 + MAX_N];
const int INF = 1e9;
int main() {
ifstream fin( "fmcm.in" );
ofstream fout( "fmcm.out" );
int n, m, S, D;
fin >> n >> m >> S >> D;
for ( int i = 0; i < m; i ++ ) {
int u, v, c, z;
fin >> u >> v >> c >> z;
edges[u].push_back( v );
edges[v].push_back( u );
cost[u][v] = z;
cost[v][u] = -z;
flow[u][v] = c;
}
for ( int i = 1; i <= n; i ++ )
if ( i != S )
dist[i] = INF;
queue<int> bellman;
bellman.push( S );
while ( bellman.size() ) {
int u = bellman.front();
bellman.pop();
for ( int v : edges[u] )
if ( flow[u][v] && dist[u] + cost[u][v] < dist[v] ) {
dist[v] = dist[u] + cost[u][v];
bellman.push( v );
}
}
for ( int u = 1; u <= n; u ++ )
for ( int v : edges[u] )
rel_cost[u][v] = cost[u][v] - dist[v] + dist[u];
int min_cost = 0, max_flow = 0;
bool improve = true;
do {
for ( int i = 1; i <= n; i ++ )
from[i] = 0;
from[S] = -1;
rel_dist[S] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> dijkstra;
dijkstra.push( make_pair( 0, S ) );
while ( dijkstra.size() && dijkstra.top().second != D ) {
int u = dijkstra.top().second, z = dijkstra.top().first;
dijkstra.pop();
if ( z != rel_dist[u] )
continue;
for ( int v : edges[u] )
if ( flow[u][v] > 0 && ( !from[v] || rel_dist[u] + rel_cost[u][v] < rel_dist[v] ) ) {
from[v] = u;
rel_dist[v] = rel_dist[u] + rel_cost[u][v];
dijkstra.push( make_pair( z + rel_cost[u][v], v ) );
}
}
if ( dijkstra.size() ) {
int f = 1e9, c = 0;
for ( int i = D; i != S; i = from[i] ) {
f = min( f, flow[from[i]][i] );
c += cost[from[i]][i];
}
for ( int i = D; i != S; i = from[i] ) {
flow[from[i]][i] -= f;
flow[i][from[i]] += f;
}
min_cost += c * f;
max_flow += f;
} else
improve = false;
} while ( improve );
fout << min_cost << endl;
return 0;
}