Cod sursa(job #2047596)

Utilizator TincaMateiTinca Matei TincaMatei Data 25 octombrie 2017 00:31:35
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 350;
const int INF = 0x3f3f3f3f;
vector<int> graph[1+MAX_N];

int kappa[1+MAX_N][1+MAX_N], cost[1+MAX_N][1+MAX_N], cost2[1+MAX_N][1+MAX_N];
int dist[1+MAX_N], papa[1+MAX_N];

bool inq[1+MAX_N];
deque<int> q;

static inline void pushQ(int nod) {
  if(!inq[nod]) {
    inq[nod] = true;
    q.push_back(nod);
  }
}

static inline int frontq() {
  int nod = q.front();
  q.pop_front();
  inq[nod] ^= 1;
  return nod;
}

void bellman(int n, int s) {
  for(int i = 1; i <= n; ++i)
    dist[i] = INF;
  dist[s] = 0;
  pushQ(s);
  while(!q.empty()) {
    int nod = frontq();
    for(auto it: graph[nod])
      if(kappa[nod][it] > 0 && dist[nod] + cost[nod][it] < dist[it]) {
        dist[it] = dist[nod] + cost[nod][it];
        pushQ(it);
      }
  }
}

int maxflow, mincost;
priority_queue<pair<int, int> > pq;

static inline int min(int a, int b) {
  if(a < b)
    return a;
  return b;
}

void pump(int s, int d) {
  int nod = d, pmp = INF, c = 0;
  while(nod != s) {
    int nod2 = papa[nod];
    pmp = min(pmp, kappa[nod2][nod]);
    c += cost[nod2][nod];
    nod = nod2;
    //printf("%d\n", nod);
  }
  maxflow += pmp;
  mincost += c * pmp;
  nod = d;
  while(nod != s) {
    int nod2 = papa[nod];
    kappa[nod2][nod] -= pmp;
    kappa[nod][nod2] += pmp;
    nod = nod2;
  }
}

bool augment(int s, int d) {
  memset(dist, 0x3f, sizeof(dist));
  dist[s] = 0;
  pq.push(make_pair(0, s));
  while(!pq.empty()) {
    pair<int,int> shit = pq.top();
    pq.pop();
    int nod = shit.second, distm = shit.first;
    if(distm == dist[nod])
      for(auto it: graph[nod])
        if(kappa[nod][it] > 0 && distm + cost2[nod][it] < dist[it]) {
          dist[it] = distm + cost2[nod][it];
          papa[it] = nod;
          pq.push(make_pair(dist[it], it));
        }
  }
  if(dist[d] < INF) {
    pump(s, d);
    return true;
  }
  return false;
}

int main() {
  int n, m, s, d, x, y, z, c;
  FILE *fin = fopen("fmcm.in", "r");
  fscanf(fin, "%d%d%d%d", &n, &m, &s, &d);
  for(int i = 0; i < m; ++i) {
    fscanf(fin, "%d%d%d%d", &x, &y, &c, &z);
    graph[x].push_back(y);
    graph[y].push_back(x);
    kappa[x][y] = c;
    cost[x][y] = z;
    cost[y][x] = -z;
  }
  fclose(fin);

  bellman(n, s);

  for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= n; ++j)
      cost2[i][j] = dist[i] + cost[i][j] - dist[j];

  while(augment(s, d));

  FILE *fout = fopen("fmcm.out", "w");
  fprintf(fout, "%d", mincost);
  fclose(fout);
  return 0;
}