Cod sursa(job #2725103)

Utilizator retrogradLucian Bicsi retrograd Data 18 martie 2021 14:05:07
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>
 
using namespace std;
using ll = long long;
const ll INF = 2e9;
 
struct ZKW {
  int n;
  vector<vector<int>> graph;
  vector<vector<ll>> F, C, K;
  vector<ll> pi; vector<int> at, vis;
 
  ZKW(int n) : n(n), graph(n), F(n, vector<ll>(n, 0)), C(F), K(C), pi(n, 0), at(n, 0) {}
 
  void AddEdge(int a, int b, ll c, ll k) {
    graph[a].push_back(b); graph[b].push_back(a);
    C[a][b] = c; 
    K[a][b] = k; K[b][a] = -k;
  }
  bool relabel() {
    ll upd = INF;
    for (int i = 0; i < n; ++i)
    for (auto j : graph[i])
      if (vis[i] && !vis[j] && F[i][j] < C[i][j])
        upd = min(upd, pi[i] + K[i][j] - pi[j]);
    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 node, int t, ll flow) {
    if (vis[node] || flow == 0) return 0;
    vis[node] = true;
    if (node == t) return flow;
    for (int& i = at[node]; i < (int)graph[node].size(); ++i) {
      int vec = graph[node][i]; ll ret;
      if (pi[vec] == pi[node] + K[node][vec] && 
          (ret = dfs(vec, t, min(flow, C[node][vec] - F[node][vec])))) 
        return F[node][vec] += ret, F[vec][node] -= 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) {
    pi.assign(n, INF); pi[s] = 0;
    for (int ch = 1; ch--; ) 
      for (int i = 0; i < n; ++i)
        for (auto j : graph[i]) 
          if (F[i][j] < C[i][j] && pi[j] > pi[i] + K[i][j])
            pi[j] = pi[i] + K[i][j], ch = 1;
  }
};
 
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;
}