Cod sursa(job #2882697)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 31 martie 2022 18:32:27
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

const int kN = 350;
int n, m, s, t, maxFlow, minCost, d[1 + kN], dp[1 + kN], par[1 + kN], q[kN * kN], C[1 + kN][1 + kN], W[1 + kN][1 + kN];
vector<int> g[1 + kN];
bitset<1 + kN> inQ;

void minSelf(int &x, int y) {
  if (y < x) {
    x = y;
  }
}

void addEdge(int u, int v, int c, int w) {
  g[u].emplace_back(v);
  g[v].emplace_back(u);
  C[u][v] += c;
  W[u][v] = w;
  W[v][u] = -w;
}

void BellmanFord() {
  for (int i = 1; i <= n; ++i) {
    d[i] = INF;
  }
  d[s] = 0;
  int l = 0, r = -1;
  q[++r] = s;
  inQ[s] = true;
  while (l <= r) {
    int u = q[l++];
    inQ[u] = false;
    for (int v : g[u]) {
      if (C[u][v] && d[v] > d[u] + W[u][v]) {
        d[v] = d[u] + W[u][v];
        if (!inQ[v]) {
          q[++r] = v;
          inQ[v] = true;
        }
      }
    }
  }
}

bool Dijkstra() {
  for (int i = 1; i <= n; ++i) {
    dp[i] = INF;
  }
  dp[s] = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
  pq.emplace(0, s);
  while (!pq.empty()) {
    int cost, u;
    tie(cost, u) = pq.top();
    pq.pop();
    if (cost != dp[u]) {
      continue;
    }
    for (int v : g[u]) {
      if (C[u][v] == 0) {
        continue;
      }
      int newCost = cost + W[u][v] + d[u] - d[v];
      if (newCost < dp[v]) {
        dp[v] = newCost;
        par[v] = u;
        pq.emplace(newCost, v);
      }
    }
  }
  if (dp[t] == INF) {
    return false;
  }
  int flow = INF;
  for (int v = t; v != s; v = par[v]) {
    minSelf(flow, C[par[v]][v]);
    if (flow == 0) {
      return false;
    }
  }
  maxFlow += flow;
  minCost += flow * (dp[t] - d[s] + d[t]);
  for (int v = t; v != s; v = par[v]) {
    C[par[v]][v] -= flow;
    C[v][par[v]] += flow;
  }
  return true;
}

void solve() {
  BellmanFord();
  while (Dijkstra());
}

void testCase() {
  fin >> n >> m >> s >> t;
  for (int i = 0; i < m; ++i) {
    int u, v, c, w;
    fin >> u >> v >> c >> w;
    addEdge(u, v, c, w);
  }
  solve();
  fout << minCost << '\n';
}

int main() {
  int tests = 1;
  for (int tc = 0; tc < tests; ++tc) {
    testCase();
  }
  fin.close();
  fout.close();
  return 0;
}