Cod sursa(job #1827296)

Utilizator cella.florescuCella Florescu cella.florescu Data 11 decembrie 2016 18:30:44
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 351;
const int INF = 2e9;

vector <int> g[MAXN];
queue <int> q;
int flow[MAXN][MAXN], cap[MAXN][MAXN], cost[MAXN][MAXN];
int father[MAXN], inq[MAXN], old_dist[MAXN], dijk_dist[MAXN], real_dist[MAXN];

int bellman(int s, int d) {
  int node;
  for (int i = 0; i < MAXN; ++i)
    old_dist[i] = INF;
  inq[s] = 1;
  old_dist[s] = 0;
  q.push(s);
  while (q.empty() == 0) {
    node = q.front();
    inq[node] = 0;
    q.pop();
    for (auto it : g[node])
      if (flow[node][it] < cap[node][it] && old_dist[it] > old_dist[node] + cost[node][it]) {
        old_dist[it] = old_dist[node] + cost[node][it];
        father[it] = node;
        if (inq[it] == 0) {
          inq[it] = 1;
          q.push(it);
        }
      }
  }
  return (old_dist[d] < INF);
}

struct PQNode {
  int node, cost;
  bool operator < (const PQNode &other) const {
    cost > other.cost;
  }
} x;

priority_queue <PQNode> pq;

int dijkstra(int s, int d) {
  int aux, i;
  for (i = 0; i < MAXN; ++i)
    dijk_dist[i] = INF;
  real_dist[s] = dijk_dist[s] = 0;
  pq.push({s, 0});
  while (pq.empty() == 0) {
    x = pq.top();
    pq.pop();
    if (x.cost == dijk_dist[x.node])
      for (auto it : g[x.node]) {
        aux = dijk_dist[x.node] + cost[x.node][it] + old_dist[x.node] - old_dist[it];
        if (flow[x.node][it] < cap[x.node][it] && dijk_dist[it] > aux) {
          father[it] = x.node;
          dijk_dist[it] = aux;
          real_dist[it] = real_dist[x.node] + cost[x.node][it];
          pq.push({it, aux});
        }
      }
  }
  memcpy(old_dist, real_dist, sizeof old_dist);
  return (dijk_dist[d] < INF);
}

inline int minimum(int A, int B) {
  if (A < B)
    return A;
  return B;
}

int main()
{
    int n, m, s, d, x, y, c, z, node, fl, ans;
    ifstream fin("fmcm.in");
    fin >> n >> m >> s >> d;
    for (int i = 0; i < m; ++i) {
      fin >> x >> y >> c >> z;
      g[x].push_back(y);
      g[y].push_back(x);
      cap[x][y] = c;
      cost[x][y] = z;
      cost[y][x] = -z;
    }
    fin.close();
    ans = 0;
    bellman(s, d);
    while (dijkstra(s, d)) {
      for (fl = INF, node = d; node != s; node = father[node])
        fl = minimum(fl, cap[father[node]][node] - flow[father[node]][node]);
      for (node = d; node != s; node = father[node]) {
        flow[father[node]][node] += fl;
        flow[node][father[node]] -= fl;
      }
      ans += fl * real_dist[d];
    }
    ofstream fout("fmcm.out");
    fout << ans << '\n';
    fout.close();
    return 0;
}