Cod sursa(job #2725085)

Utilizator retrogradLucian Bicsi retrograd Data 18 martie 2021 13:54:43
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
const ll INF = 2e9;

struct ZKW {
  struct Edge { int a, b; ll f, c, k; };
  int n;
  vector<Edge> E;
  vector<vector<int>> graph;
  vector<ll> pi; vector<int> at, vis;

  ZKW(int n) : n(n), graph(n), at(n, 0), pi(n, 0) {}

  void AddEdge(int a, int b, ll c, ll k) {
    graph[a].push_back(E.size()); 
    E.push_back({a, b, 0, c, k}); 
    graph[b].push_back(E.size()); 
    E.push_back({b, a, 0, 0, -k}); 
  }
  bool relabel() {
    ll upd = INF;
    for (auto& e : E) if (vis[e.a] && !vis[e.b] && e.f < e.c)
      upd = min(upd, pi[e.a] + e.k - pi[e.b]);
    assert(upd >= 0);
    for (int i = 0; i < n; ++i) if (!vis[i]) pi[i] += upd;
    at.assign(n, 0);
    return upd != INF;
  }
  ll dfs(int v, int t, ll flow) {
    if (vis[v] || flow == 0) return 0;
    vis[v] = true;
    if (v == t) return flow;
    for (int& i = at[v]; i < (int)graph[v].size(); ++i) {
      int ei = graph[v][i]; auto& e = E[ei]; ll ret;
      if (pi[e.b] == pi[e.a] + e.k && 
          (ret = dfs(e.b, t, min(flow, e.c - e.f)))) 
        return E[ei].f += ret, E[ei^1].f -= ret, ret; 
    }
    return 0;
  }
  pair<ll, ll> Compute(int s, int t) {
    ll flow = 0, cost = 0, f;
    while (true) {
      vis.assign(n, 0);
      if (!(f = dfs(s, t, INF)) && !relabel()) break;
      flow += f; cost += f * pi[t];
    }
    return {flow, cost};
  }
  void SetPi(int s) {
    vector<bool> inq(n, false);
    pi.assign(n, INF);
    vector<int> q(n + 1); int b = 0, e = 0;
    auto push = [&](int x, ll y) {
      if (pi[x] <= y) return;
      pi[x] = y;
      if (inq[x]) return;
      inq[x] = true; q[e++] = x;
      if (e > n) e = 0;
    };
    push(s, 0);
    while (b != e) {
      int node = q[b++]; inq[node] = false;
      if (b > n) b = 0;
      for (auto ei : graph[node]) {
        auto& e = E[ei];
        if (e.f < e.c)
          push(e.b, pi[e.a] + e.k);
      }
    }   
  }
};

int main() {
  ifstream cin("fmcm.in");
  ofstream cout("fmcm.out");
  int n, m, s, t; cin >> n >> m >> s >> t; --s; --t;
  ZKW F(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c, k; cin >> a >> b >> c >> k; 
    F.AddEdge(a - 1, b - 1, c, k);
  }
  F.SetPi(s);
  cout << F.Compute(s, t).second << endl;
  return 0;
}