Pagini recente » Cod sursa (job #973700) | Cod sursa (job #1818236) | Cod sursa (job #594082) | Cod sursa (job #1488783) | Cod sursa (job #2945494)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 350;
const int INF = 1e9;
ifstream fin( "fmcm.in" );
ofstream fout( "fmcm.out" );
vector <int> edges[NMAX+1];
int capacity[NMAX+1][NMAX+1];
int cost[NMAX+1][NMAX+1];
void addEgde( int a, int b, int cap, int c ) {
edges[a].push_back( b );
edges[b].push_back( a );
capacity[a][b] = cap;
cost[a][b] = c;
cost[b][a] = -c;
}
int n, source, dest;
int dist[NMAX+1];
queue <int> q;
bool marked[NMAX+1];
void bellman() {
int i, qfront;
for( i = 1; i <= n; i++ ) {
dist[i] = INF;
marked[i] = false;
}
q.push( source );
marked[source] = true;
while( !q.empty() ) {
qfront = q.front();
marked[qfront] = false;
q.pop();
for( auto vec: edges[qfront] ) {
if( dist[vec] > dist[qfront] + cost[qfront][vec] && capacity[qfront][vec] ) {
dist[vec] = dist[qfront] + cost[qfront][vec];
if( !marked[vec] )
q.push( vec );
}
}
}
}
struct elemInPq {
int node, cost;
bool operator<( const elemInPq &x ) const {
return cost > x.cost;
}
};
priority_queue <elemInPq> pq;
int fakeDist[NMAX+1], goodDist[NMAX+1];
int parent[NMAX+1];
int viz[NMAX+1];
int edgeWithNewCost( int a, int b ) {
return goodDist[a] + cost[a][b] - goodDist[b];
}
void dijkstra() {
int i;
for( i = 1; i <= n; i++ ) {
viz[i] = false;
goodDist[i] = dist[i];
fakeDist[i] = INF;
parent[i] = 0;
}
pq.push( { source, 0 } );
fakeDist[source] = dist[source] = 0;
parent[source] = -1;
while( !pq.empty() ) {
auto qfront = pq.top().node;
pq.pop();
if( !viz[qfront] ) {
viz[qfront] = true;
for( auto vec: edges[qfront] ) {
if( fakeDist[vec] > fakeDist[qfront] + edgeWithNewCost( qfront, vec ) && capacity[qfront][vec] ) {
parent[vec] = qfront;
fakeDist[vec] = fakeDist[qfront] + edgeWithNewCost( qfront, vec );
dist[vec] = dist[qfront] + cost[qfront][vec];
pq.push( { vec, fakeDist[vec] } );
}
}
}
}
}
int fmcm() {
int node, flow, new_flow, minCost, costAlongTheEdges;
bellman();
dijkstra();
flow = minCost = 0;
while( parent[dest] ) {
node = dest;
new_flow = INF;
while( node != source ) {
new_flow = min( new_flow, capacity[parent[node]][node] );
node = parent[node];
}
node = dest;
costAlongTheEdges = 0;
while( node != source ) {
capacity[parent[node]][node] -= new_flow;
capacity[node][parent[node]] += new_flow;
costAlongTheEdges += cost[parent[node]][node];
node = parent[node];
}
flow += new_flow;
minCost += new_flow * costAlongTheEdges;
dijkstra();
}
return minCost;
}
int main() {
int m, i, a, b, c, cap;
fin >> n >> m >> source >> dest;
for( i = 0; i < m; i++ ) {
fin >> a >> b >> cap >> c;
addEgde( a, b, cap, c );
}
fout << fmcm();
return 0;
}