Cod sursa(job #3301703)

Utilizator IanisBelu Ianis Ianis Data 29 iunie 2025 11:38:46
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.71 kb
#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second

#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()

template<typename T>
bool ckmax(T &a, T b) { return a < b ? a = b, true : false; }
template<typename T>
bool ckmin(T &a, T b) { return a > b ? a = b, true : false; }

using ll = long long;
using pii = pair<int, int>;

const int INF = 1e9+5;

struct FlowGraph {
   struct Edge {
      int y, cap, cost, rev;
   };

   const int S = 0, D = 1;

   vector<int> dist;
   vector<bool> inq;
   vector<pii> prev;
   vector<vector<Edge>> g;

   FlowGraph() {
      add_node();
      add_node();
   }

   int add_node() {
      dist.push_back(0);
      inq.push_back(false);
      prev.push_back({});
      g.emplace_back();
      return sz(g) - 1;
   }

   void add_edge(int x, int y, int cap, int cost) {
      g[x].push_back({ y, cap, cost, sz(g[y]) });
      g[y].push_back({ x, 0, -cost, sz(g[x]) - 1 });
   }

   bool bellman() {
      fill(all(dist), INF);
      fill(all(inq), false);

      queue<int> q;
      q.push(S);
      inq[S] = true;
      dist[S] = 0;

      while (!q.empty()) {
         int x = q.front();
         q.pop();
         inq[x] = false;

         int i = 0;
         for (auto &[ y, cap, cost, _ ] : g[x]) {
            if (cap && ckmin(dist[y], dist[x] + cost)) {
               if (!inq[y]) {
                  inq[y] = true;
                  q.push(y);
               }
               prev[y] = { x, i };
            }
            i++;
         }
      }

      return dist[D] != INF;
   }

   pii compute() {
      int max_flow = 0, min_cost = 0;

      while (bellman()) {
         int flow = INF, x = D;
         
         while (x != S) {
            auto [ y, i ] = prev[x];
            flow = min(flow, g[y][i].cap);
            x = y;
         }

         x = D;
         while (x != S) {
            auto [ y, i ] = prev[x];
            g[y][i].cap -= flow;
            g[x][g[y][i].rev].cap += flow;
            x = y;
         }

         max_flow += flow;
         min_cost += flow * dist[D];
      }

      return { max_flow, min_cost };
   }
};

const int NMAX = 355;

int a[NMAX];

signed main() {
#ifdef LOCAL
   freopen("input.txt", "r", stdin);
#else
   freopen("fmcm.in", "r", stdin);
   freopen("fmcm.out", "w", stdout);
#endif

   ios_base::sync_with_stdio(false);
   cin.tie(0);
   cout.tie(0);

   int n, m, S, D;
   FlowGraph f;

   cin >> n >> m >> S >> D;

   for (int i = 1; i <= n; i++) {
      if (i != S && i != D) {
         a[i] = f.add_node();
      }
   }

   a[S] = f.S;
   a[D] = f.D;

   for (int i = 1, x, y, c, w; i <= m; i++) {
      cin >> x >> y >> c >> w;
      f.add_edge(a[x], a[y], c, w);
   }

   cout << f.compute().se << endl;
   
   return 0;
}