Cod sursa(job #2945492)

Utilizator vladburacBurac Vlad vladburac Data 23 noiembrie 2022 20:23:09
Problema Flux maxim de cost minim Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#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;
void bellman() {
  int i, qfront;
  for( i = 1; i <= n; i++ )
    dist[i] = INF;
  q.push( source );
  while( !q.empty() ) {
    qfront = q.front();
    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];
        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;
}