Cod sursa(job #2910581)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 22 iunie 2022 14:17:06
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.95 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

const long long INF = (1LL << 60);

struct Edge {
  int from, to;
  int cap, cost;
};

class Graph {
 private:
  int n;
  int src, dst;
  vector<Edge> edges;
  vector<vector<int>> gr;
  vector<long long> d;
 
 public:
  Graph(int _n, int _src, int _dst) {
    n = _n;
    src = _src, dst = _dst;
    gr.resize(_n + 1);
    d.assign(_n + 1, INF);
  }
  void addEdge(int from, int to, int cap, int cost) {
    gr[from].push_back(edges.size());
    edges.push_back({from, to, cap, cost});
    gr[to].push_back(edges.size());
    edges.push_back({to, from, 0, -cost});
  }
  void bellmanFord() {
    queue<int> q;
    vector<bool> inQ(n + 1, false);
    
    d.assign(n + 1, INF);
    d[src] = 0, inQ[src] = true;
    q.push(src);
    while (!q.empty()) {
      auto node = q.front();
      inQ[node] = false;
      q.pop();
      
      for (auto idx: gr[node]) {
        auto e = edges[idx];
        if (e.cap > 0 && d[e.to] > d[node] + e.cost) {
          d[e.to] = d[node] + e.cost;
          if (!inQ[e.to]) {
            inQ[e.to] = true;
            q.push(e.to);
          }
        }
      }
    }
  }
  void assignCost() {
    for (auto& e: edges) {
      e.cost += d[e.from] - d[e.to];
    }
  }
  bool dijkstra(vector<int>& ant) {
    vector<long long> dij(n + 1, INF);
    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;
    dij[src] = 0;
    pq.push({dij[src], src});
    ant.assign(n + 1, -1);

    while (!pq.empty()) {
      auto p = pq.top();
      pq.pop();

      int node = p.second;
      if (node == dst) {
        break;
      }
      for (auto idx: gr[node]) {
        auto e = edges[idx];
        if (e.cap > 0 && dij[e.to] > dij[node] + e.cost) {
          dij[e.to] = dij[node] + e.cost;
          ant[e.to] = idx;
          pq.push({dij[e.to], e.to});
        }
      }
    }

    return (dij[dst] != INF);
  }
  pair<long long, long long> maxFlowMinCost() {
    bellmanFord();
    assignCost();

    long long maxFlow = 0, minCost = 0;
    vector<int> ant;
    while (dijkstra(ant)) {
      int minFlow = 2e9;
      int node = dst;
      while (node != src) {
        auto e = edges[ant[node]];
        minFlow = min(minFlow, e.cap);
        node = e.from;
      }

      maxFlow += minFlow;
      node = dst;
      while (node != src) {
        auto& e = edges[ant[node]];
        auto& re = edges[ant[node] ^ 1];
        minCost += (long long) minFlow * (e.cost - (d[e.from] - d[e.to]));
        e.cap -= minFlow;
        re.cap += minFlow;
        node = e.from;
      }
    }
    return {maxFlow, minCost};
  }
};

int main() {
  ifstream cin("fmcm.in");
  ofstream cout("fmcm.out");
  int n, m, s, t;
  cin >> n >> m >> s >> t;
  Graph g(n, s, t);
  while (m--) {
    int from, to, cap, cost;
    cin >> from >> to >> cap >> cost;
    g.addEdge(from, to, cap, cost);
  }
  cin.close();

  auto ans = g.maxFlowMinCost();
  cout << ans.second << "\n";
  cout.close();
  return 0;
}