Cod sursa(job #2078710)

Utilizator DruffbaumPopescu Vlad Druffbaum Data 29 noiembrie 2017 20:38:58
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>

const int MAXN = 3e2 + 5e1;
const int INF = 0x3f3f3f3f;

struct Edge {
  int u, c;
  bool operator <(const Edge &aux) const {
    return c > aux.c;
  }
};

std::vector <int> g[MAXN + 1];
int flow[MAXN + 1][MAXN + 1], cap[MAXN + 1][MAXN + 1],
    fath[MAXN + 1], vis[MAXN + 1], odist[MAXN + 1],
    rdist[MAXN + 1], ddist[MAXN + 1],
    cost[MAXN + 1][MAXN + 1];
std::queue <int> q;
std::priority_queue <Edge> pq;

static inline int min(int a, int b) {
  return a > b ? b : a;
}

void bellman(int s, int d) {
  int u;
  memset(odist, INF, sizeof(odist));
  odist[s] = 0;
  q.push(s);
  while (!q.empty()) {
    u = q.front();
    q.pop();
    vis[u] = 0;
    for (auto v: g[u]) {
      if (flow[u][v] < cap[u][v] && odist[v] > odist[u] + cost[u][v]) {
        odist[v] = odist[u] + cost[u][v];
        fath[v] = u;
        if (!vis[v]) {
          q.push(v);
          vis[v] = 1;
        }
      }
    }
  }
}

bool dijkstra(int s, int d) {
  Edge x;
  int tmp;
  memset(ddist, INF, sizeof(ddist));
  ddist[s] = rdist[s] = 0;
  pq.push({s, 0});
  while (!pq.empty()) {
    x = pq.top();
    pq.pop();
    if (ddist[x.u] == x.c) {
      for (auto v: g[x.u]) {
        tmp = cost[x.u][v] + ddist[x.u] + odist[x.u] - odist[v];
        if (flow[x.u][v] < cap[x.u][v] && tmp < ddist[v]) {
          ddist[v] = tmp;
          rdist[v] = rdist[x.u] + cost[x.u][v];
          fath[v] = x.u;
          pq.push({v, tmp});
        }
      }
    }
  }
  memcpy(odist, rdist, sizeof(odist));
  return (ddist[d] < INF);
}

int main() {
  int n, m, s, d, u, v, c, z, fl, maxfl;
  FILE *f = fopen("fmcm.in", "r");
  fscanf(f, "%d%d%d%d", &n, &m, &s, &d);
  for (int i = 0; i < m; ++i) {
    fscanf(f, "%d%d%d%d", &u, &v, &c, &z);
    g[u].push_back(v);
    g[v].push_back(u);
    cap[u][v] = c;
    cost[u][v] = z;
    cost[v][u] = -z;
  }
  fclose(f);   
  bellman(s, d);
  maxfl = 0;
  while (dijkstra(s, d)) {
    u = d;
    fl = INF;
    while (u != s) {
      fl = min(fl, cap[fath[u]][u] - flow[fath[u]][u]);
      u = fath[u];
    }
    u = d;
    while (u != s) {
      flow[fath[u]][u] += fl;
      flow[u][fath[u]] -= fl;
      u = fath[u];
    }
    maxfl += fl * rdist[d];
  }
  f = fopen("fmcm.out", "w");
  fprintf(f, "%d\n", maxfl);
  fclose(f);
  return 0;
}