Cod sursa(job #3038879)

Utilizator cadmium_Voicu Mihai Valeriu cadmium_ Data 27 martie 2023 21:19:29
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.51 kb
#include <bits/stdc++.h>
#define all(x) (x).begin(),(x).end()
using namespace std;

using ll = long long;

#ifndef DLOCAL
  #define cin fin
  #define cout fout
  ifstream cin("fmcm.in");
  ofstream cout("fmcm.out");
#endif



//#define int ll
#define sz(x) ((int)(x).size())

using pii = pair<int,int>;
using tii = tuple<int,int,int>;

const int inf = 1e9 + 5;

struct Flux {
  struct Edg {
    int other, cost, flux, cap;
  };
  vector<Edg> edg;
  vector<vector<int>> g;
  vector<int> p;
  //vector<int> potential;
  vector<int> dist;
  vector<int> inque;
  vector<int> f;
  //vector<int> 
  int S, T;
  
  void init(int s, int t, int n) {
    g.resize(n);
    //potential.resize(n);
    dist.resize(n);
    inque.resize(n);
    f.resize(n);
    p.resize(n);
    S = s;
    T = t;
  }
  void addedg(int u, int v, int c, int w) {
    g[u].emplace_back(sz(edg));
    edg.emplace_back(Edg{v, w, 0, c});
    g[v].emplace_back(sz(edg));
    edg.emplace_back(Edg{u, -w, 0, 0});
  }
  
  void SPFA() {
    fill(all(dist), inf);
    fill(all(inque), 0);
    fill(all(f), -1);
    queue<int> que;
    inque[S] = 1;
    dist[S] = 0;
    p[S] = -1;
    f[S] = inf;
    que.emplace(S);
    while(!que.empty()) {
      auto node = que.front();
      //cerr << dist[node] << ' ' << node << '\t' << S << '\t' << T << '\n';
      que.pop();
      inque[node] = 0;
      for(auto e : g[node]) {
        if(edg[e].flux < edg[e].cap && dist[edg[e].other] > dist[node] + edg[e].cost) {
          dist[edg[e].other] = dist[node] + edg[e].cost;
          f[edg[e].other] = min(f[node], edg[e].cap - edg[e].flux);
          p[edg[e].other] = e;
          if(!inque[edg[e].other])
            inque[edg[e].other] = 1,
            que.emplace(edg[e].other);
        }
      }
    }
    return;
  }
  
  pair<int,int> flux() {
    int cost = 0, flow = 0;
    while(true) {      
      SPFA();
      if(f[T] == -1) break;
      flow += f[T];
      cost += f[T] * dist[T];
      int current_edg = p[T];
      while(current_edg != -1) {
        edg[current_edg].flux += f[T];
        edg[current_edg ^ 1].flux -= f[T];
        current_edg = p[edg[current_edg ^ 1].other];
      }
    }
    return pii{cost, flow};
  }
};

signed main() {
  int n, m, s, d;
  cin >> n >> m >> s >> d;
  Flux cuspfa;
  cuspfa.init(s, d, n + 1);
  for(int i = 0, x, y, c, z; i < m; i++) {
    cin >> x >> y >> c >> z;
    cuspfa.addedg(x, y, c, z);
  }
  auto [cost, flow] = cuspfa.flux();
  cout << cost << '\n';
}

/**
      Vom spune că toamna a venit... foarte trist -
-- George Bacovia, Scântei galbene
*/